From a89abdf793550ce0af2ade0cf18b9db685986efa Mon Sep 17 00:00:00 2001 From: Yuval Hayun <70104171+YuvHayun@users.noreply.github.com> Date: Sun, 18 Feb 2024 13:14:35 +0200 Subject: [PATCH 001/272] update tanium v2 readme (#32975) --- Packs/Tanium/Integrations/Tanium_v2/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Packs/Tanium/Integrations/Tanium_v2/README.md b/Packs/Tanium/Integrations/Tanium_v2/README.md index 53ec90bf84df..afff0db4017a 100644 --- a/Packs/Tanium/Integrations/Tanium_v2/README.md +++ b/Packs/Tanium/Integrations/Tanium_v2/README.md @@ -59,7 +59,7 @@ The integration was tested with 4.x version of Tanium Threat Response, and is co
  • OAuth 2.0 Authentication - To use OAuth 2.0 follow the next steps:
      -
    1. Follow the instructions here to create an API token. +
    2. Follow the instructions here to create an API token.
    3. Paste the generated API Token into the API Token parameter in the instance configuration, and leave the username and password fields empty.
    4. Click the Test button to validate the instance configuration.
    5. @@ -74,7 +74,7 @@ The integration was tested with 4.x version of Tanium Threat Response, and is co the api_token_expiration_in_days global setting (minimum value is 1), or include a value with the expire_in_days field when you create the token.
    6. To edit a global setting in the Tanium platform, go to Administration -> Global Settings and search for the setting you would like to edit.
    7. -
    8. For more information see the Tanium documentation.
    9. +
    10. For more information see the Tanium documentation.

    Commands

    From a17d9499d917561defe4e6c1701e3eabd173e5ae Mon Sep 17 00:00:00 2001 From: Yehuda Rosenberg <90599084+RosenbergYehuda@users.noreply.github.com> Date: Sun, 18 Feb 2024 14:47:05 +0200 Subject: [PATCH 002/272] Revert "YR/Handle long running pipelines, and commits with no pipelines/CIAC-9386 (#32462)" (#32974) This reverts commit 29aa622d6aebb5b27f5eec510caa3ee90a2f25c8. Co-authored-by: Michael Yochpaz <8832013+MichaelYochpaz@users.noreply.github.com> --- Tests/scripts/common.py | 180 +++--------------- Tests/scripts/gitlab_slack_notifier.py | 58 ++---- .../infrastructure_tests/common_test.py | 152 ++------------- 3 files changed, 60 insertions(+), 330 deletions(-) diff --git a/Tests/scripts/common.py b/Tests/scripts/common.py index fd8a58baddff..dc6aabdf9d8b 100644 --- a/Tests/scripts/common.py +++ b/Tests/scripts/common.py @@ -12,7 +12,6 @@ from Tests.scripts.utils import logging_wrapper as logging from gitlab.v4.objects.pipelines import ProjectPipeline from gitlab.v4.objects.commits import ProjectCommit -from itertools import pairwise CONTENT_NIGHTLY = 'Content Nightly' @@ -258,9 +257,9 @@ def get_pipelines_and_commits(gitlab_client: Gitlab, project_id, return pipelines, commits -def get_person_in_charge(commit: ProjectCommit) -> tuple[str, str, str] | tuple[None, None, None]: +def get_person_in_charge(commit): """ - Returns the name of the person in charge of the commit, the PR link and the beginning of the PR name. + Returns the name, email, and PR link for the author of the provided commit. Args: commit: The Gitlab commit object containing author info. @@ -268,63 +267,55 @@ def get_person_in_charge(commit: ProjectCommit) -> tuple[str, str, str] | tuple[ Returns: name: The name of the commit author. pr: The GitHub PR link for the Gitlab commit. - beginning_of_pr_name: The beginning of the PR name. """ name = commit.author_name # pr number is always the last id in the commit title, starts with a number sign, may or may not be in parenthesis. pr_number = commit.title.split("#")[-1].strip("()") - beginning_of_pr_name = commit.title[:20] + "..." if pr_number.isnumeric(): pr = f"https://github.com/demisto/content/pull/{pr_number}" - return name, pr, beginning_of_pr_name + return name, pr else: - return None, None, None + return None, None -def are_pipelines_in_order(pipeline_a: ProjectPipeline, pipeline_b: ProjectPipeline) -> bool: +def are_pipelines_in_order(current_pipeline: ProjectPipeline, previous_pipeline: ProjectPipeline) -> bool: """ - Check if the pipelines are in the same order of their commits. + This function checks if the current pipeline was created after the previous pipeline, to avoid rare conditions + that pipelines are not in the same order as the commits. Args: - pipeline_a: The first pipeline object. - pipeline_b: The second pipeline object. + current_pipeline: The current pipeline object. + previous_pipeline: The previous pipeline object. Returns: bool """ - pipeline_a_timestamp = parser.parse(pipeline_a.created_at) - pipeline_b_timestamp = parser.parse(pipeline_b.created_at) - return pipeline_a_timestamp > pipeline_b_timestamp + previous_pipeline_timestamp = parser.parse(previous_pipeline.created_at) + current_pipeline_timestamp = parser.parse(current_pipeline.created_at) + return current_pipeline_timestamp > previous_pipeline_timestamp -def is_pivot(current_pipeline: ProjectPipeline, pipeline_to_compare: ProjectPipeline) -> bool | None: +def is_pivot(current_pipeline: ProjectPipeline, previous_pipeline: ProjectPipeline) -> bool | None: """ Is the current pipeline status a pivot from the previous pipeline status. Args: current_pipeline: The current pipeline object. - pipeline_to_compare: a pipeline object to compare to. + previous_pipeline: The previous pipeline object. Returns: True status changed from success to failed False if the status changed from failed to success None if the status didn't change or the pipelines are not in order of commits """ - in_order = are_pipelines_in_order(pipeline_a=current_pipeline, pipeline_b=pipeline_to_compare) + in_order = are_pipelines_in_order(current_pipeline, previous_pipeline) if in_order: - if pipeline_to_compare.status == 'success' and current_pipeline.status == 'failed': + if previous_pipeline.status == 'success' and current_pipeline.status == 'failed': return True - if pipeline_to_compare.status == 'failed' and current_pipeline.status == 'success': + if previous_pipeline.status == 'failed' and current_pipeline.status == 'success': return False return None def get_reviewer(pr_url: str) -> str | None: - """ - Get the first reviewer who approved the PR. - Args: - pr_url: The URL of the PR. - Returns: - The name of the first reviewer who approved the PR. - """ approved_reviewer = None try: # Extract the owner, repo, and pull request number from the URL @@ -346,14 +337,6 @@ def get_reviewer(pr_url: str) -> str | None: def get_slack_user_name(name: str | None, name_mapping_path: str) -> str: - """ - Get the slack user name for a given Github name. - Args: - name: The name to convert. - name_mapping_path: The path to the name mapping file. - Returns: - The slack user name. - """ with open(name_mapping_path) as map: mapping = json.load(map) # If the name is the name of the 'docker image update bot' reviewer - return the owner of that bot. @@ -364,131 +347,30 @@ def get_slack_user_name(name: str | None, name_mapping_path: str) -> str: def get_commit_by_sha(commit_sha: str, list_of_commits: list[ProjectCommit]) -> ProjectCommit | None: - """ - Get a commit by its SHA. - Args: - commit_sha: The SHA of the commit. - list_of_commits: A list of commits. - Returns: - The commit object. - """ return next((commit for commit in list_of_commits if commit.id == commit_sha), None) def get_pipeline_by_commit(commit: ProjectCommit, list_of_pipelines: list[ProjectPipeline]) -> ProjectPipeline | None: - """ - Get a pipeline by its commit. - Args: - commit: The commit object. - list_of_pipelines: A list of pipelines. - Returns: - The pipeline object. - """ return next((pipeline for pipeline in list_of_pipelines if pipeline.sha == commit.id), None) -def create_shame_message(suspicious_commits: list[ProjectCommit], - pipeline_changed_status: bool, name_mapping_path: str) -> tuple[str, str, str, str] | None: +def create_shame_message(current_commit: ProjectCommit, + pipeline_changed_status: bool, name_mapping_path: str) -> tuple[str, str, str] | None: """ - Create a shame message for the person in charge of the commit, or for multiple people in case of multiple suspicious commits. - Args: - suspicious_commits: A list of suspicious commits. - pipeline_changed_status: A boolean indicating if the pipeline status changed. - name_mapping_path: The path to the name mapping file. - Returns: - A tuple of strings containing the message, the person in charge, the PR link and the color of the message. + Create a shame message for the person in charge of the commit. """ - hi_and_status = person_in_charge = in_this_pr = color = "" - for suspicious_commit in suspicious_commits: - name, pr, beginning_of_pr = get_person_in_charge(suspicious_commit) - if name and pr and beginning_of_pr: - if name == CONTENT_BOT: - name = get_reviewer(pr) - name = get_slack_user_name(name, name_mapping_path) - msg = "broken" if pipeline_changed_status else "fixed" - color = "danger" if pipeline_changed_status else "good" - emoji = ":cry:" if pipeline_changed_status else ":muscle:" - if suspicious_commits.index(suspicious_commit) == 0: - hi_and_status = f"Hi, The build was {msg} {emoji} by:" - person_in_charge = f"@{name}" - in_this_pr = f" That was done in this PR: {slack_link(pr, beginning_of_pr)}" - - else: - person_in_charge += f" or @{name}" - in_this_pr = "" - - return (hi_and_status, person_in_charge, in_this_pr, color) if hi_and_status and person_in_charge and color else None + name, pr = get_person_in_charge(current_commit) + if name and pr: + if name == CONTENT_BOT: + name = get_reviewer(pr) + name = get_slack_user_name(name, name_mapping_path) + msg = "broke" if pipeline_changed_status else "fixed" + color = "danger" if pipeline_changed_status else "good" + emoji = ":cry:" if pipeline_changed_status else ":muscle:" + return (f"Hi @{name}, You {msg} the build! {emoji} ", + f" That was done in this {slack_link(pr,'PR.')}", color) + return None def slack_link(url: str, text: str) -> str: - """ - Create a slack link. - Args: - url: The URL to link to. - text: The text to display. - Returns: - The slack link. - """ return f"<{url}|{text}>" - - -def was_message_already_sent(commit_index: int, list_of_commits: list, list_of_pipelines: list) -> bool: - """ - Check if a message was already sent for newer commits, this is possible if pipelines of later commits, - finished before the pipeline of the current commit. - Args: - commit_index: The index of the current commit. - list_of_commits: A list of commits. - list_of_pipelines: A list of pipelines. - Returns: - - """ - for previous_commit, current_commit in pairwise(reversed(list_of_commits[:commit_index])): - current_pipeline = get_pipeline_by_commit(current_commit, list_of_pipelines) - previous_pipeline = get_pipeline_by_commit(previous_commit, list_of_pipelines) - # in rare cases some commits have no pipeline - if current_pipeline and previous_pipeline and (is_pivot(current_pipeline, previous_pipeline) is not None): - return True - return False - - -def get_nearest_newer_commit_with_pipeline(list_of_pipelines: list[ProjectPipeline], list_of_commits: list[ProjectCommit], - current_commit_index: int) -> tuple[ProjectPipeline, list] | tuple[None, None]: - """ - Get the nearest newer commit that has a pipeline. - Args: - list_of_pipelines: A list of pipelines. - list_of_commits: A list of commits. - current_commit_index: The index of the current commit. - Returns: - A tuple of the nearest pipeline and a list of suspicious commits that have no pipelines. - """ - suspicious_commits = [] - for index in reversed(range(0, current_commit_index - 1)): - next_commit = list_of_commits[index] - suspicious_commits.append(list_of_commits[index + 1]) - next_pipeline = get_pipeline_by_commit(next_commit, list_of_pipelines) - if next_pipeline: - return next_pipeline, suspicious_commits - return None, None - - -def get_nearest_older_commit_with_pipeline(list_of_pipelines: list[ProjectPipeline], list_of_commits: list[ProjectCommit], - current_commit_index: int) -> tuple[ProjectPipeline, list] | tuple[None, None]: - """ - Get the nearest oldest commit that has a pipeline. - Args: - list_of_pipelines: A list of pipelines. - list_of_commits: A list of commits. - current_commit_index: The index of the current commit. - Returns: - A tuple of the nearest pipeline and a list of suspicious commits that have no pipelines. - """ - suspicious_commits = [] - for index in range(current_commit_index, len(list_of_commits) - 1): - previous_commit = list_of_commits[index + 1] - suspicious_commits.append(list_of_commits[index]) - previous_pipeline = get_pipeline_by_commit(previous_commit, list_of_pipelines) - if previous_pipeline: - return previous_pipeline, suspicious_commits - return None, None diff --git a/Tests/scripts/gitlab_slack_notifier.py b/Tests/scripts/gitlab_slack_notifier.py index fb2354c92a24..eca50e9e9136 100644 --- a/Tests/scripts/gitlab_slack_notifier.py +++ b/Tests/scripts/gitlab_slack_notifier.py @@ -25,8 +25,7 @@ replace_escape_characters from Tests.scripts.github_client import GithubPullRequest from Tests.scripts.common import get_pipelines_and_commits, is_pivot, get_commit_by_sha, get_pipeline_by_commit, \ - create_shame_message, slack_link, was_message_already_sent, get_nearest_newer_commit_with_pipeline, \ - get_nearest_older_commit_with_pipeline + create_shame_message, slack_link from Tests.scripts.test_modeling_rule_report import calculate_test_modeling_rule_results, \ read_test_modeling_rule_to_jira_mapping, get_summary_for_test_modeling_rule, TEST_MODELING_RULES_TO_JIRA_TICKETS_CONVERTED from Tests.scripts.test_playbooks_report import read_test_playbook_to_jira_mapping, TEST_PLAYBOOKS_TO_JIRA_TICKETS_CONVERTED @@ -361,7 +360,7 @@ def construct_slack_msg(triggering_workflow: str, pipeline_url: str, pipeline_failed_jobs: list[ProjectPipelineJob], pull_request: GithubPullRequest | None, - shame_message: tuple[str, str, str, str] | None) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + shame_message: tuple[str, str, str] | None) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: # report failing jobs content_fields = [] @@ -442,9 +441,9 @@ def construct_slack_msg(triggering_workflow: str, title += title_append slack_msg_start = [] if shame_message: - hi_and_status, person_in_charge, in_this_pr, shame_color = shame_message + shame_title, shame_value, shame_color = shame_message slack_msg_start.append({ - "title": f"{hi_and_status}\n{person_in_charge}\n{in_this_pr}", + "title": f"{shame_title}\n{shame_value}", "color": shame_color }) return slack_msg_start + [{ @@ -562,53 +561,32 @@ def main(): pipeline_url, pipeline_failed_jobs = collect_pipeline_data(gitlab_client, project_id, pipeline_id) shame_message = None - computed_slack_channel = "dmst-build-test" if options.current_branch == DEFAULT_BRANCH and triggering_workflow == CONTENT_MERGE: - # Check if the current commit's pipeline differs from the previous one. If the previous pipeline is still running, - # compare the next build. For commits without pipelines, compare the current one to the nearest commit with a - # pipeline and all those in between, marking them as suspicious. + # We check if the previous build failed and this one passed, or wise versa. list_of_pipelines, list_of_commits = get_pipelines_and_commits(gitlab_client=gitlab_client, project_id=project_id, look_back_hours=LOOK_BACK_HOURS) current_commit = get_commit_by_sha(commit_sha, list_of_commits) if current_commit: current_commit_index = list_of_commits.index(current_commit) - # If the current commit is the last commit in the list, there is no previous commit, # since commits are in ascending order - # or if we already sent a shame message for newer commits, we don't want to send another one for older commits. - if (current_commit_index != len(list_of_commits) - 1 - and not was_message_already_sent(current_commit_index, list_of_commits, list_of_pipelines)): + if current_commit_index != len(list_of_commits) - 1: + previous_commit = list_of_commits[current_commit_index + 1] current_pipeline = get_pipeline_by_commit(current_commit, list_of_pipelines) - - # looking backwards until we find a commit with a pipeline to compare with - previous_pipeline, suspicious_commits = get_nearest_older_commit_with_pipeline( - list_of_pipelines, list_of_commits, current_commit_index) - if previous_pipeline and suspicious_commits and current_pipeline: - pipeline_changed_status = is_pivot(current_pipeline=current_pipeline, - pipeline_to_compare=previous_pipeline) - + previous_pipeline = get_pipeline_by_commit(previous_commit, list_of_pipelines) + if current_pipeline and previous_pipeline: + pipeline_changed_status = is_pivot(current_pipeline, previous_pipeline) logging.info( - f"Checking pipeline id: {current_pipeline.id}, of commit: {current_commit.title}, " - f"after comparing with pipeline id: {previous_pipeline.id}," - f"the change status is: {pipeline_changed_status}") - - if pipeline_changed_status is None and current_commit_index > 0: - # looking_forward until we find a commit with a pipeline to compare with - next_pipeline, suspicious_commits = get_nearest_newer_commit_with_pipeline( - list_of_pipelines, list_of_commits, current_commit_index) - - if next_pipeline and suspicious_commits: - pipeline_changed_status = is_pivot(current_pipeline=next_pipeline, - pipeline_to_compare=current_pipeline) - logging.info( - f" after comparing with pipeline id: {next_pipeline.id}," - f"the change status is: {pipeline_changed_status}") - + f"Checking pipeline {current_pipeline}, the commit is {current_commit} " + f"and the pipeline change status is: {pipeline_changed_status}" + ) if pipeline_changed_status is not None: - shame_message = create_shame_message(suspicious_commits, pipeline_changed_status, # type: ignore - options.name_mapping_path) + shame_message = create_shame_message( + current_commit, pipeline_changed_status, options.name_mapping_path + ) computed_slack_channel = "test_slack_notifier_when_master_is_broken" - + else: + computed_slack_channel = "dmst-build-test" slack_msg_data, threaded_messages = construct_slack_msg(triggering_workflow, pipeline_url, pipeline_failed_jobs, pull_request, shame_message) diff --git a/Tests/scripts/infrastructure_tests/common_test.py b/Tests/scripts/infrastructure_tests/common_test.py index de51808ddab9..47f71e6a2e3b 100644 --- a/Tests/scripts/infrastructure_tests/common_test.py +++ b/Tests/scripts/infrastructure_tests/common_test.py @@ -1,9 +1,11 @@ from pathlib import Path -from Tests.scripts.common import get_reviewer, get_person_in_charge, are_pipelines_in_order, is_pivot, get_slack_user_name, \ - was_message_already_sent, get_nearest_newer_commit_with_pipeline, get_nearest_older_commit_with_pipeline +from Tests.scripts.common import get_reviewer, get_person_in_charge, are_pipelines_in_order, is_pivot, get_slack_user_name from requests_mock import MockerCore +NAME_AND_PR_URL = ('John Doe', 'https://github.com/demisto/content/pull/123') + + def test_get_person_in_charge(mocker): """ Given: @@ -11,14 +13,14 @@ def test_get_person_in_charge(mocker): When: The function get_person_in_charge is called with that commit Then: - It should return a tuple with the author name and the pull request URL and the title beginning (up to 20 characters) + It should return a tuple with the author name and the pull request URL """ commit = mocker.Mock() commit.author_name = 'John Doe' commit.title = 'Fix a bug (#123)' result = get_person_in_charge(commit) - assert result == ('John Doe', 'https://github.com/demisto/content/pull/123', 'Fix a bug (#123)...') + assert result == NAME_AND_PR_URL def test_get_person_in_charge__multiple_IDs(mocker): @@ -28,15 +30,14 @@ def test_get_person_in_charge__multiple_IDs(mocker): When: The function get_person_in_charge is called with that commit Then: - It should return the a tuple with the author name and the pull request URL, with only the last ID in the URL, - and the title beginning (up to 20 characters) + It should return the a tuple with the author name and the pull request URL, with only the last ID in the URL """ commit = mocker.Mock() commit.author_name = 'John Doe' commit.title = 'Fix a bug (#456) (#123)' result = get_person_in_charge(commit) - assert result == ('John Doe', 'https://github.com/demisto/content/pull/123', 'Fix a bug (#456) (#1...') + assert result == NAME_AND_PR_URL def test_get_person_in_charge__no_parenthesis(mocker): @@ -46,15 +47,14 @@ def test_get_person_in_charge__no_parenthesis(mocker): When: The function get_person_in_charge is called with the commit Then: - It should return the author name and the pull request URL (even if the ID was not in parenthesis) - and the title beginning (up to 20 characters) + It should return the author name and the pull request URL even if the ID was not in parenthesis """ commit = mocker.Mock() commit.author_name = 'John Doe' commit.title = 'Fix a bug #123' result = get_person_in_charge(commit) - assert result == ('John Doe', 'https://github.com/demisto/content/pull/123', 'Fix a bug #123...') + assert result == NAME_AND_PR_URL def test_get_person_in_charge__no_number_sign(mocker): @@ -71,7 +71,7 @@ def test_get_person_in_charge__no_number_sign(mocker): commit.title = 'Fix a bug (123)' result = get_person_in_charge(commit) - assert result == (None, None, None) + assert result == (None, None) def test_pipelines_are_in_correct_order__false(mocker): @@ -302,133 +302,3 @@ def test_get_slack_user_name__name_is_github_actions_bot(): name = "github-actions[bot]" result = get_slack_user_name(name, str(Path(__file__).parent / 'tests_data/test_mapping.json')) assert result == "docker images bot owner" - - -COMMITS = ['commit1', 'commit2', 'commit3', 'commit4', 'commit5'] -PIPELINES = ['pipeline1', 'pipeline2', 'pipeline3', 'pipeline4', 'pipeline5'] - - -def test_was_message_already_sent__was_sent_for_true_pivot(mocker): - """ - Given: - An index of a commit and a list of commits and pipelines with a positive pivot in newer pipelines - When: - The function was_message_already_sent is called with the index, commits and pipelines - Then: - It should return True since the message was already sent for newer pipelines - """ - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', side_effect=lambda commit, pipelines: commit) - mocker.patch('Tests.scripts.common.is_pivot', return_value=True) - - assert was_message_already_sent(2, COMMITS, PIPELINES) is True - - -def test_was_message_already_sent__was_sent_for_false_pivot(mocker): - """ - Given: - An index of a commit and a list of commits and pipelines with a negative pivot in newer pipelines - When: - The function was_message_already_sent is called with the index, commits and pipelines - Then: - It should return True since the message was already sent for newer pipelines - """ - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', side_effect=lambda commit, pipelines: commit) - mocker.patch('Tests.scripts.common.is_pivot', return_value=False) - assert was_message_already_sent(2, COMMITS, PIPELINES) is True - - -def test_was_message_already_sent__was_not_sent(mocker): - """ - Given: - An index of a commit and a list of commits and pipelines with a no pivots in newer pipelines - When: - The function was_message_already_sent is called with the index, commits and pipelines - Then: - It should return False since the message was not sent for newer pipelines - """ - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', side_effect=lambda commit, pipelines: commit) - mocker.patch('Tests.scripts.common.is_pivot', return_value=None) - assert was_message_already_sent(2, COMMITS, PIPELINES) is False - - -def test_was_message_already_sent__was_not_sent_no_pipeline(mocker): - """ - Given: - An index of a commit that has no pipeline and a list of commits and pipelines with a positive pivot in newer pipelines - When: - The function was_message_already_sent is called with the index, commits and pipelines - Then: - It should return False since the message was not sent for newer pipelines since current commit has no pipeline - """ - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', side_effect=lambda commit, pipelines: commit) - mocker.patch('Tests.scripts.common.is_pivot', return_value=True) - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', side_effect=lambda commit, - pipelines: None if commit == 'commit2' else commit) - assert was_message_already_sent(2, COMMITS, PIPELINES) is False - - -def test_get_nearest_newer_commit__with_pipeline(mocker): - """ - Given: - A list of commits and pipelines, but only the first commit has a pipeline - When: - The function get_nearest_commit_with_pipeline is called with the list of commits, - the index of current commit and "newer" as the direction - Then: - It should return the first commit since he is the closest with a pipeline, - and a list of all commits between the first commit and the current one that are suspicious - """ - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', side_effect=lambda commit, - pipelines: commit if commit == 'commit1' else None) - pipeline, suspicious_commits = get_nearest_newer_commit_with_pipeline(PIPELINES, COMMITS, 3) - assert pipeline == 'commit1' - assert suspicious_commits == ['commit3', 'commit2'] - - -def test_get_nearest_older_commit__with_pipeline(mocker): - """ - Given: - A list of commits and pipelines, but only the last commit has a pipeline - When: - The function get_nearest_older_commit_with_pipeline is called with the list of commits, - Then: - It should return the last commit since he is the closest with a pipeline, - and a list of all commits between the last commit and the current one that are suspicious - """ - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', side_effect=lambda commit, - pipelines: commit if commit == 'commit5' else None) - pipeline, suspicious_commits = get_nearest_older_commit_with_pipeline(PIPELINES, COMMITS, 1) - assert pipeline == 'commit5' - assert suspicious_commits == ['commit2', 'commit3', 'commit4'] - - -def test_get_nearest_newer_commit_with_pipeline__no_pipelines(mocker): - """ - Given: - A list of commits and pipelines, but no commit has a pipeline - When: - The function get_nearest_newer_commit_with_pipeline is called with the list of commits, - Then: - It should return None since no commit has a pipeline. - """ - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', return_value='pipeline_for_commit') - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', return_value=None) - pipeline, suspicious_commits = get_nearest_newer_commit_with_pipeline(PIPELINES, COMMITS, 2) - assert pipeline is None - assert suspicious_commits is None - - -def test_get_nearest_older_commit_with_pipeline__no_pipelines(mocker): - """ - Given: - A list of commits and pipelines, but no commit has a pipeline - When: - The function get_nearest_older_commit_with_pipeline is called with the list of commits, - Then: - It should return None since no commit has a pipeline. - """ - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', return_value='pipeline_for_commit') - mocker.patch('Tests.scripts.common.get_pipeline_by_commit', return_value=None) - pipeline, suspicious_commits = get_nearest_older_commit_with_pipeline(PIPELINES, COMMITS, 2) - assert pipeline is None - assert suspicious_commits is None From ef002a1b327de0bbc538768ad369126c63fdfb80 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 18 Feb 2024 15:01:50 +0200 Subject: [PATCH 003/272] MISP 2.1.41 - Add Custom Object command (#32955) * MISP 2.1.41 - Add Custom Object command (#32881) * MISP 2.1.41 - add-custom-object command * Updated release notes * Updated MISPV3_test.py * Update Packs/MISP/ReleaseNotes/2_1_41.md Co-authored-by: Yuval Hayun <70104171+YuvHayun@users.noreply.github.com> * Updated MISPV3.py * Revert Docker Version --------- Co-authored-by: Yuval Hayun <70104171+YuvHayun@users.noreply.github.com> * Update Packs/MISP/ReleaseNotes/2_1_41.md Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> --------- Co-authored-by: Martin Ohl Co-authored-by: Yuval Hayun <70104171+YuvHayun@users.noreply.github.com> Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> --- Packs/MISP/Integrations/MISPV3/MISPV3.py | 45 +++++++++ Packs/MISP/Integrations/MISPV3/MISPV3.yml | 91 +++++++++++++++++++ Packs/MISP/Integrations/MISPV3/MISPV3_test.py | 35 +++++++ Packs/MISP/Integrations/MISPV3/README.md | 52 +++++++++++ .../MISPV3/test_data/response_add_object.json | 65 +++++++++++++ .../test_data/response_object_templates.json | 31 +++++++ .../response_raw_object_template.json | 52 +++++++++++ Packs/MISP/ReleaseNotes/2_1_41.md | 3 + Packs/MISP/pack_metadata.json | 2 +- 9 files changed, 375 insertions(+), 1 deletion(-) create mode 100644 Packs/MISP/Integrations/MISPV3/test_data/response_add_object.json create mode 100644 Packs/MISP/Integrations/MISPV3/test_data/response_object_templates.json create mode 100644 Packs/MISP/Integrations/MISPV3/test_data/response_raw_object_template.json create mode 100644 Packs/MISP/ReleaseNotes/2_1_41.md diff --git a/Packs/MISP/Integrations/MISPV3/MISPV3.py b/Packs/MISP/Integrations/MISPV3/MISPV3.py index df7427799834..eaefc0263a8f 100644 --- a/Packs/MISP/Integrations/MISPV3/MISPV3.py +++ b/Packs/MISP/Integrations/MISPV3/MISPV3.py @@ -302,6 +302,28 @@ def build_generic_object(template_name: str, args: list[dict]) -> GenericObjectG return misp_object +def build_custom_object(template_name: str, args: list[dict]): + obj = PYMISP.object_templates() + for entry in obj: + if str(entry.get('ObjectTemplate').get('name')).lower() == template_name: + + custom_obj = PYMISP.get_raw_object_template(template_name) + + if not os.path.exists('/tmp/{}'.format(template_name)): + os.mkdir('/tmp/{}'.format(template_name)) + open('/tmp/{}/definition.json'.format(template_name), 'w').write(json.dumps(custom_obj)) + + misp_object = MISPObject(name=template_name, misp_objects_path_custom='/tmp') + + for arg in args: + for key, value in arg.items(): + misp_object.add_attribute(key, value) + + return misp_object + + return False + + def misp_convert_timestamp_to_date_string(timestamp: str | int) -> str: """ Gets a timestamp from MISP response (1546713469) and converts it to human readable format @@ -1496,6 +1518,27 @@ def add_generic_object_command(demisto_args: dict): f'`attribute` parameter could not be decoded, may not a valid JSON\nattribute: {attributes}', str(e)) +def add_custom_object_command(demisto_args: dict): + event_id = demisto_args.get('event_id', '') + template = demisto_args.get('template', '') + attributes = demisto_args.get('attributes', '').replace("'", '"') + + try: + args = json.loads(attributes) + if not isinstance(args, list): + args = dict_to_generic_object_format(args) + + obj = build_custom_object(template, args) + if obj is not False: + return add_object(event_id, obj) + else: + raise DemistoException('Unable to find custom template {}'. format(template)) + + except ValueError as e: + raise DemistoException( + f'`attribute` parameter could not be decoded, may not a valid JSON\nattribute: {attributes}', str(e)) + + def convert_arg_to_misp_args(demisto_args, args_names): return [{arg.replace('_', '-'): demisto_args.get(arg)} for arg in args_names if demisto_args.get(arg)] @@ -1768,6 +1811,8 @@ def main(): return_results(add_ip_object(args)) elif command == 'misp-add-object': return_results(add_generic_object_command(args)) + elif command == 'misp-add-custom-object': + return_results(add_custom_object_command(args)) elif command == 'misp-update-attribute': return_results(update_attribute_command(args)) elif command == 'misp-delete-attribute': diff --git a/Packs/MISP/Integrations/MISPV3/MISPV3.yml b/Packs/MISP/Integrations/MISPV3/MISPV3.yml index 77b5193f05d7..86d9ec7eb0fd 100644 --- a/Packs/MISP/Integrations/MISPV3/MISPV3.yml +++ b/Packs/MISP/Integrations/MISPV3/MISPV3.yml @@ -2120,6 +2120,97 @@ script: - contextPath: MISP.Event.Object.Description description: Description of the object. type: String + - arguments: + - description: ID of the event to add the object to. + name: event_id + required: true + - description: Custom Template name. + name: template + required: true + - description: 'Attributes. For example, {"description": "Manager Ferrari", "make": "Ferrari", "model": "308 GTS"}.' + name: attributes + required: true + description: Adds custom objects to MISP. + name: misp-add-custom-object + outputs: + - contextPath: MISP.Event.ID + description: MISP event ID. + type: number + - contextPath: MISP.Event.Object.MetaCategory + description: Object meta category. + type: String + - contextPath: MISP.Event.Object.Distribution + description: Distribution of the object. + type: Number + - contextPath: MISP.Event.Object.Name + description: Name of the object. + type: String + - contextPath: MISP.Event.Object.TemplateVersion + description: Template version of the object. + type: Number + - contextPath: MISP.Event.Object.EventID + description: ID of the event in which the object was first created. + type: Number + - contextPath: MISP.Event.Object.TemplateUUID + description: UUID of the template. + type: String + - contextPath: MISP.Event.Object.LastChanged + description: Timestamp when the object was last changed. + type: String + - contextPath: MISP.Event.Object.Deleted + description: Whether the object was deleted. + type: Boolean + - contextPath: MISP.Event.Object.ID + description: ID of the object. + type: Number + - contextPath: MISP.Event.Object.UUID + description: UUID of the object. + type: String + - contextPath: MISP.Event.Object.Attribute.Value + description: Value of the attribute. + type: String + - contextPath: MISP.Event.Object.Attribute.EventID + description: ID of the first event from which the object originated. + type: Number + - contextPath: MISP.Event.Object.Attribute.LastChanged + description: Attribute last changed timestamp. + type: Date + - contextPath: MISP.Event.Object.Attribute.Deleted + description: Whether the object was deleted?. + type: Boolean + - contextPath: MISP.Event.Object.Attribute.ObjectID + description: ID of the object. + type: Number + - contextPath: MISP.Event.Object.Attribute.DisableCorrelation + description: Whether correlation is disabled. + type: Boolean + - contextPath: MISP.Event.Object.Attribute.ID + description: ID of the attribute. + type: Unknown + - contextPath: MISP.Event.Object.Attribute.ObjectRelation + description: Relation of the object. + type: String + - contextPath: MISP.Event.Object.Attribute.Type + description: Object type. + type: String + - contextPath: MISP.Event.Object.Attribute.UUID + description: UUID of the attribute. + type: String + - contextPath: MISP.Event.Object.Attribute.ToIDs + description: Whether the to_ids flag is on. + type: Boolean + - contextPath: MISP.Event.Object.Attribute.Category + description: Category of the attribute. + type: String + - contextPath: MISP.Event.Object.Attribute.SharingGroupID + description: ID of the sharing group. + type: Number + - contextPath: MISP.Event.Object.Attribute.Comment + description: Comment of the attribute. + type: String + - contextPath: MISP.Event.Object.Description + description: Description of the object. + type: String - arguments: - description: ID of a MISP event. name: event_id diff --git a/Packs/MISP/Integrations/MISPV3/MISPV3_test.py b/Packs/MISP/Integrations/MISPV3/MISPV3_test.py index 15e4b9353db4..46e7fe9a90d0 100644 --- a/Packs/MISP/Integrations/MISPV3/MISPV3_test.py +++ b/Packs/MISP/Integrations/MISPV3/MISPV3_test.py @@ -721,6 +721,41 @@ def test_add_msg_email_object(mocker): assert 'misp-add-email-object command does not support *.msg files' in str(exception_info.value) +def test_add_custom_object(mocker): + """ + Given: + - A custom template name. + When: + - Running add_custom_object command. + Then: + - Ensure that the readable output is valid. + """ + from MISPV3 import add_custom_object_command + event_id = 1572 + + result_object_templates = util_load_json('test_data/response_object_templates.json') + mocker.patch('MISPV3.PYMISP.object_templates', return_value=result_object_templates) + + response_raw_obj_tempalte = util_load_json('test_data/response_raw_object_template.json') + mocker.patch('MISPV3.PYMISP.get_raw_object_template', return_value=response_raw_obj_tempalte) + + response_add_obj = util_load_json('test_data/response_add_object.json') + mocker.patch('MISPV3.PYMISP.add_object', return_value=response_add_obj) + + demisto_args = { + "event_id": event_id, + "template": "corporate-asset", + "attributes": "{'asset-type': 'Server','asset-id': '1','text': 'test text'}" + } + + result = add_custom_object_command(demisto_args) + expected_output = { + 'readable_output': 'Object has been added to MISP event ID {}'.format(event_id), + 'outputs': response_add_obj + } + assert result.readable_output == expected_output['readable_output'] + + @pytest.mark.parametrize( 'demisto_args, is_attribute, expected_result', [ diff --git a/Packs/MISP/Integrations/MISPV3/README.md b/Packs/MISP/Integrations/MISPV3/README.md index e1fb66269bbf..162e22bbd48c 100644 --- a/Packs/MISP/Integrations/MISPV3/README.md +++ b/Packs/MISP/Integrations/MISPV3/README.md @@ -3650,6 +3650,58 @@ Adds any other object to MISP. >Object has been added to MISP event ID 1655 +### misp-add-custom-object + +*** +Adds custom objects to MISP. + +#### Base Command + +`misp-add-custom-object` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| event_id | ID of the event to add the object to. | Required | +| template | Custom Template name. | Required | +| attributes | Attributes. For example, {"description": "Manager Ferrari", "make": "Ferrari", "model": "308 GTS"}. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| MISP.Event.ID | number | MISP event ID. | +| MISP.Event.Object.MetaCategory | String | Object meta category. | +| MISP.Event.Object.Distribution | Number | Distribution of the object. | +| MISP.Event.Object.Name | String | Name of the object. | +| MISP.Event.Object.TemplateVersion | Number | Template version of the object. | +| MISP.Event.Object.EventID | Number | ID of the event in which the object was first created. | +| MISP.Event.Object.TemplateUUID | String | UUID of the template. | +| MISP.Event.Object.LastChanged | String | Timestamp when the object was last changed. | +| MISP.Event.Object.Deleted | Boolean | Whether the object was deleted. | +| MISP.Event.Object.ID | Number | ID of the object. | +| MISP.Event.Object.UUID | String | UUID of the object. | +| MISP.Event.Object.Attribute.Value | String | Value of the attribute. | +| MISP.Event.Object.Attribute.EventID | Number | ID of the first event from which the object originated. | +| MISP.Event.Object.Attribute.LastChanged | Date | Attribute last changed timestamp. | +| MISP.Event.Object.Attribute.Deleted | Boolean | Whether the object was deleted?. | +| MISP.Event.Object.Attribute.ObjectID | Number | ID of the object. | +| MISP.Event.Object.Attribute.DisableCorrelation | Boolean | Whether correlation is disabled. | +| MISP.Event.Object.Attribute.ID | Unknown | ID of the attribute. | +| MISP.Event.Object.Attribute.ObjectRelation | String | Relation of the object. | +| MISP.Event.Object.Attribute.Type | String | Object type. | +| MISP.Event.Object.Attribute.UUID | String | UUID of the attribute. | +| MISP.Event.Object.Attribute.ToIDs | Boolean | Whether the to_ids flag is on. | +| MISP.Event.Object.Attribute.Category | String | Category of the attribute. | +| MISP.Event.Object.Attribute.SharingGroupID | Number | ID of the sharing group. | +| MISP.Event.Object.Attribute.Comment | String | Comment of the attribute. | +| MISP.Event.Object.Description | String | Description of the object. | + +#### Command Example + +```!misp-add-custom-object event_id="1572" template="corporate-asset" attributes="{\"asset-type\":\"Server\",\"asset-id\":\"12\",\"text\":\"Asset Details\"}"``` + ### misp-add-ip-object *** diff --git a/Packs/MISP/Integrations/MISPV3/test_data/response_add_object.json b/Packs/MISP/Integrations/MISPV3/test_data/response_add_object.json new file mode 100644 index 000000000000..519001959a0d --- /dev/null +++ b/Packs/MISP/Integrations/MISPV3/test_data/response_add_object.json @@ -0,0 +1,65 @@ +{ + "Object": + { + "id": "20524", + "name": "corporate-asset", + "meta-category": "misc", + "description": "Corporate asset", + "template_uuid": "1a99327a-bbe6-493d-97da-fce83965eccd", + "template_version": "20210317", + "event_id": "1572", + "uuid": "1642924e-c749-4758-b0e4-f1f9d8474393", + "timestamp": "1707861295", + "distribution": "5", + "sharing_group_id": "0", + "comment": "", + "deleted": false, + "first_seen": null, + "last_seen": null, + "Attribute": + [ + { + "id": "285625", + "event_id": "1572", + "object_id": "20524", + "object_relation": "asset-type", + "category": "Other", + "type": "text", + "value1": "Server", + "value2": "", + "to_ids": false, + "uuid": "7399c837-8044-49be-b313-52192cf18af8", + "timestamp": "1707861295", + "distribution": "5", + "sharing_group_id": "0", + "comment": "", + "deleted": false, + "disable_correlation": true, + "first_seen": null, + "last_seen": null, + "value": "Server" + }, + { + "id": "285626", + "event_id": "1572", + "object_id": "20524", + "object_relation": "asset-id", + "category": "Targeting data", + "type": "target-machine", + "value1": "1", + "value2": "", + "to_ids": false, + "uuid": "b7143b40-ae18-4b15-8e8e-af4bce5f906c", + "timestamp": "1707861295", + "distribution": "5", + "sharing_group_id": "0", + "comment": "", + "deleted": false, + "disable_correlation": true, + "first_seen": null, + "last_seen": null, + "value": "1" + } + ] + } +} \ No newline at end of file diff --git a/Packs/MISP/Integrations/MISPV3/test_data/response_object_templates.json b/Packs/MISP/Integrations/MISPV3/test_data/response_object_templates.json new file mode 100644 index 000000000000..a0ed35df491b --- /dev/null +++ b/Packs/MISP/Integrations/MISPV3/test_data/response_object_templates.json @@ -0,0 +1,31 @@ +[ + { + "ObjectTemplate": + { + "id": "300", + "user_id": "1", + "org_id": "1", + "uuid": "1a99327a-bbe6-493d-97da-fce83965eccd", + "name": "corporate-asset", + "meta-category": "misc", + "description": "Corporate asset", + "version": "20210317", + "requirements": + { + "required": + [ + "asset-type", + "asset-id" + ] + }, + "fixed": true, + "active": true + }, + "Organisation": + { + "id": "1", + "name": "Palo", + "uuid": "8d1fff3b-a47a-4629-9b5e-1907e25cca99" + } + } +] \ No newline at end of file diff --git a/Packs/MISP/Integrations/MISPV3/test_data/response_raw_object_template.json b/Packs/MISP/Integrations/MISPV3/test_data/response_raw_object_template.json new file mode 100644 index 000000000000..a81ceb824f66 --- /dev/null +++ b/Packs/MISP/Integrations/MISPV3/test_data/response_raw_object_template.json @@ -0,0 +1,52 @@ +{ + "description": "Corporate asset", + "meta-category": "misc", + "name": "corporate-asset", + "required": + [ + "asset-type", + "asset-id" + ], + "uuid": "1a99327a-bbe6-493d-97da-fce83965eccd", + "version": 20210317, + "attributes": + { + "asset-type": + { + "description": "Type of asset", + "disable_correlation": true, + "misp-attribute": "text", + "ui-priority": 3, + "values_list": + [ + "Server", + "Workstation", + "Printer", + "Network", + "Mobile", + "Monitor" + ] + }, + "asset-id": + { + "description": "Asset identification", + "disable_correlation": true, + "misp-attribute": "target-machine", + "ui-priority": 0 + }, + "business-unit": + { + "description": "Organizational business unit associated with the asset", + "disable_correlation": true, + "misp-attribute": "target-org", + "ui-priority": 2 + }, + "text": + { + "description": "A description of the asset.", + "disable_correlation": true, + "misp-attribute": "text", + "ui-priority": 1 + } + } +} \ No newline at end of file diff --git a/Packs/MISP/ReleaseNotes/2_1_41.md b/Packs/MISP/ReleaseNotes/2_1_41.md new file mode 100644 index 000000000000..09341431629d --- /dev/null +++ b/Packs/MISP/ReleaseNotes/2_1_41.md @@ -0,0 +1,3 @@ +#### Integrations +##### MISP v3 +- Added the ***misp-add-custom-object*** command. diff --git a/Packs/MISP/pack_metadata.json b/Packs/MISP/pack_metadata.json index 49aa2988e19e..72fbbc8605da 100644 --- a/Packs/MISP/pack_metadata.json +++ b/Packs/MISP/pack_metadata.json @@ -2,7 +2,7 @@ "name": "MISP", "description": "Malware information and threat sharing platform.", "support": "xsoar", - "currentVersion": "2.1.40", + "currentVersion": "2.1.41", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 9765f29bfac204f81d6f2002498012109a4f7ad2 Mon Sep 17 00:00:00 2001 From: Darya Koval <72339940+daryakoval@users.noreply.github.com> Date: Sun, 18 Feb 2024 15:09:01 +0200 Subject: [PATCH 004/272] Zimperium v2Integration (#32615) * saving initial integration * added fetch + fixes in the commands * unitests and output descriptions * pre-commit fix * trying to fix fetch * trying to fix fetch * rn; mapper; last fixes; * incident field * remove conf.json * added mapper * fixes from cr * fixes from cr * adding readme, pre-commit fixes * adding readme fixes * fix for test module * limit fix * fix readme * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * docker, coverage * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * fix validation on readme * limit and page_size * save fixes from the demo * filter report by improtance * fixes in pre-commit after demo * fixed a release notes * change the search params descriptioin * changes from thr cr * pre-commit fix * fromversion 6.9 to pass the build * fromversion 6.9 to pass the build --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- Packs/Zimperium/.secrets-ignore | 2 + ...sifier-Zimperium_v2_-_Incoming_Mapper.json | 31 + .../incidentfield-Zimperium_Bundle_ID.json | 31 + .../Integrations/ZimperiumV2/README.md | 1759 +++++++++++++ .../Integrations/ZimperiumV2/ZimperiumV2.py | 1105 ++++++++ .../Integrations/ZimperiumV2/ZimperiumV2.yml | 1353 ++++++++++ .../ZimperiumV2/ZimperiumV2_description.md | 14 + .../ZimperiumV2/ZimperiumV2_image.png | Bin 0 -> 3297 bytes .../ZimperiumV2/ZimperiumV2_test.py | 418 +++ .../ZimperiumV2/command_examples.txt | 16 + .../test_data/app_version_list.json | 74 + .../test_data/cve_devices_get.json | 62 + .../ZimperiumV2/test_data/device_cve_get.json | 65 + .../ZimperiumV2/test_data/device_search.json | 192 ++ .../test_data/devices_os_version.json | 46 + .../test_data/policy_app_settings.json | 48 + .../policy_device_inactivity_get.json | 36 + .../policy_device_inactivity_list.json | 12 + .../test_data/policy_group_list.json | 83 + .../test_data/policy_phishing.json | 42 + .../ZimperiumV2/test_data/policy_privacy.json | 61 + .../ZimperiumV2/test_data/policy_threat.json | 69 + .../ZimperiumV2/test_data/report_get.json | 61 + .../ZimperiumV2/test_data/threat_search.json | 238 ++ .../ZimperiumV2/test_data/users_search.json | 25 + .../test_data/vulnerability_get.json | 41 + .../layoutscontainer-Zimperium_event.json | 9 + Packs/Zimperium/ReleaseNotes/2_0_0.md | 23 + .../Zimperiumv2-TestPlaybook.yml | 2293 +++++++++++++++++ Packs/Zimperium/pack_metadata.json | 2 +- Tests/conf.json | 6 +- 31 files changed, 8215 insertions(+), 2 deletions(-) create mode 100644 Packs/Zimperium/Classifiers/classifier-Zimperium_v2_-_Incoming_Mapper.json create mode 100644 Packs/Zimperium/IncidentFields/incidentfield-Zimperium_Bundle_ID.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/README.md create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2.py create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2.yml create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2_description.md create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2_image.png create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2_test.py create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/command_examples.txt create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/app_version_list.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/cve_devices_get.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/device_cve_get.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/device_search.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/devices_os_version.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/policy_app_settings.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/policy_device_inactivity_get.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/policy_device_inactivity_list.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/policy_group_list.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/policy_phishing.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/policy_privacy.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/policy_threat.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/report_get.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/threat_search.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/users_search.json create mode 100644 Packs/Zimperium/Integrations/ZimperiumV2/test_data/vulnerability_get.json create mode 100644 Packs/Zimperium/ReleaseNotes/2_0_0.md create mode 100644 Packs/Zimperium/TestPlaybooks/Zimperiumv2-TestPlaybook.yml diff --git a/Packs/Zimperium/.secrets-ignore b/Packs/Zimperium/.secrets-ignore index 640a9a093c20..97f9d0062c14 100644 --- a/Packs/Zimperium/.secrets-ignore +++ b/Packs/Zimperium/.secrets-ignore @@ -83,3 +83,5 @@ http://www.webrtc.org 64.233.178.82 216.58.194.110 172.217.14.170 +https://test_url.com +https://mtduat.zimperium.com diff --git a/Packs/Zimperium/Classifiers/classifier-Zimperium_v2_-_Incoming_Mapper.json b/Packs/Zimperium/Classifiers/classifier-Zimperium_v2_-_Incoming_Mapper.json new file mode 100644 index 000000000000..bda405985aa1 --- /dev/null +++ b/Packs/Zimperium/Classifiers/classifier-Zimperium_v2_-_Incoming_Mapper.json @@ -0,0 +1,31 @@ +{ + "description": "", + "feed": false, + "id": "Zimperium v2 - Incoming Mapper", + "mapping": { + "Zimperium Event": { + "dontMapEventToLabels": true, + "internalMapping": { + "App": { + "simple": "zappInstance.name" + }, + "Zimperium Bundle ID": { + "simple": "zappInstance.bundleId" + }, + "Mobile Device Model": { + "simple": "device.model" + }, + "OS": { + "simple": "device.os.name" + }, + "OS Version": { + "simple": "device.os.version" + } + } + } + }, + "name": "Zimperium v2 - Incoming Mapper", + "type": "mapping-incoming", + "version": -1, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/Zimperium/IncidentFields/incidentfield-Zimperium_Bundle_ID.json b/Packs/Zimperium/IncidentFields/incidentfield-Zimperium_Bundle_ID.json new file mode 100644 index 000000000000..fcaa48d4aba6 --- /dev/null +++ b/Packs/Zimperium/IncidentFields/incidentfield-Zimperium_Bundle_ID.json @@ -0,0 +1,31 @@ +{ + "id": "incident_zimperiumbundleid", + "version": -1, + "modified": "2024-02-01T09:42:52.067562173Z", + "name": "Zimperium Bundle ID", + "ownerOnly": false, + "cliName": "zimperiumbundleid", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "Zimperium Event" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": true, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/Zimperium/Integrations/ZimperiumV2/README.md b/Packs/Zimperium/Integrations/ZimperiumV2/README.md new file mode 100644 index 000000000000..d475ea75be48 --- /dev/null +++ b/Packs/Zimperium/Integrations/ZimperiumV2/README.md @@ -0,0 +1,1759 @@ +Fetch and investigate mobile security alerts, generated based on anomalous or unauthorized activities detected on a user's mobile device. +This integration was integrated and tested with version v.5.24.0 of Zimperium v2. + +Some changes have been made that might affect your existing content. +If you are upgrading from a previous version of this integration, see [Breaking Changes](#breaking-changes-from-the-previous-version-of-this-integration). + +## Configure Zimperium v2 on Cortex XSOAR + +1. Navigate to **Settings** > **Integrations** > **Servers & Services**. +2. Search for Zimperium v2. +3. Click **Add instance** to create and configure a new integration instance. + + | **Parameter** | **Description** | **Required** | + | --- | --- | --- | + | Server URL (e.g., https://mtduat.zimperium.com) | | True | + | Client ID | | True | + | Client Secret | | True | + | Fetch incidents | | False | + | Search Params (e.g, severityName=CRITICAL,teamId=myId) | Comma-separated list of search parameters and its values. Same as for the "zimperium-threat-search" command. | False | + | Max fetch | | False | + | First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days) | | False | + | Advanced: Minutes to look back when fetching | Use this parameter to determine how far back to look in the search for incidents that were created before the last run time and did not match the query when they were created. | False | + | Trust any certificate (not secure) | | False | + | Use system proxy settings | | False | + | Incident type | | | + +4. Click **Test** to validate the URLs, token, and connection. + +## Commands + +You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. +After you successfully execute a command, a DBot message appears in the War Room with the command details. + +### zimperium-users-search + +*** +Search users. Only a user created as a "Team admin" is authorized to perform this request. Also, it will only get information about the teams that this user is associated with. Users that are not part of any team (such as account admin) won’t appear in the response. + +#### Base Command + +`zimperium-users-search` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| user_id | The ID of the user to search. | Optional | +| page_size | Maximum number of results to retrieve in each page. If a limit is not provided, default is 50. | Optional | +| page | Page number. Default is 0. | Optional | +| limit | Number of total results to return. Default is 50. | Optional | +| team_id | Used to filter the user data by the team the user belongs to. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.User.id | String | The ID of the Zimperium user. | +| Zimperium.User.created | Date | The date and time that the user was created. | +| Zimperium.User.email | String | The email address of the user. | +| Zimperium.User.firstName | String | The first name of the user. | +| Zimperium.User.languagePreference | Unknown | The language preference for the user. | +| Zimperium.User.lastLogin | Unknown | The time of the last login of the user. | +| Zimperium.User.lastName | String | The last name of the user. | +| Zimperium.User.middleName | Unknown | The middle name of the user. | +| Zimperium.User.modified | Date | The date and time that the user was modified. | +| Zimperium.User.notificationEmail | String | The email address for the user's notifications. | +| Zimperium.User.phone | Unknown | The phone number of the user. | +| Zimperium.User.role.id | String | The role identifier of the user. | +| Zimperium.User.role.name | String | The role name of the user. | +| Zimperium.User.role.scopeBounds | String | The role scope for a user. | +| Zimperium.User.teams.id | String | The ID of the team of the user. | +| Zimperium.User.teams.name | String | The name of the team of the user. | +| Zimperium.User.validated | Boolean | The user's validated status. | + +#### Command example +```!zimperium-users-search user_id="1" team_id="1"``` +#### Context Example +```json +{ + "Zimperium": { + "User": { + "created": "2024-01-21T11:02:08.789+00:00", + "email": "email1@email.com", + "firstName": "name", + "id": "1", + "languagePreference": null, + "lastLogin": null, + "lastName": "name", + "middleName": null, + "modified": "2024-01-21T11:02:08.789+00:00", + "notificationEmail": "email1@email.com", + "phone": null, + "role": { + "id": "1", + "name": "Team Admin", + "scopeBounds": "TEAM_BOUNDED" + }, + "teams": [ + { + "id": "1", + "name": "Default" + } + ], + "validated": false + } + } +} +``` + +#### Human Readable Output + +>### Users Search Results +>| Id | First Name | Last Name |Email|Created|Role|Teams| +>|----|------------|-----------|---|---|---|---| +>| 1 | name | name | email1@email.com | 2024-01-21T11:02:08.789+00:00 | scopeBounds: TEAM_BOUNDED
    name: Team Admin
    id: 1 | {'name': 'Default', 'id': '1'} | + + +### zimperium-devices-search + +*** +Search devices. + +#### Base Command + +`zimperium-devices-search` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| device_id | The ID of the device to search for. | Optional | +| page_size | Maximum number of results to retrieve in each page. If a limit is not provided, default is 50. | Optional | +| page | Page number. Default is 0. | Optional | +| limit | Number of total results to return. Default is 50. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.Device.accountId | String | The account identifier of the device. | +| Zimperium.Device.activationName | String | The activation name of the device. | +| Zimperium.Device.additionalDeviceInfo | Unknown | The additional device information. | +| Zimperium.Device.agentType | Number | The agent type of the device. | +| Zimperium.Device.appStatus | String | The app status. | +| Zimperium.Device.appVersions | Unknown | The app version of the device. | +| Zimperium.Device.bundleId | Unknown | The bundle identifier of the device. | +| Zimperium.Device.created | Date | The date and time that the device was created. | +| Zimperium.Device.deleted | Boolean | Whether the device was deleted. | +| Zimperium.Device.developerOptionsOn | Boolean | Whether the developer options are on. | +| Zimperium.Device.deviceOwner.email | String | The email address of the device owner. | +| Zimperium.Device.fullType | String | The device's full type. | +| Zimperium.Device.groupId | String | The device group identifier. | +| Zimperium.Device.id | String | The unique identifier of the device. | +| Zimperium.Device.lastSeen | Date | The time when the device was last seen. | +| Zimperium.Device.lockScreenUnprotected | Boolean | Whether the device's lockscreen is unprotected or not. | +| Zimperium.Device.model | String | The model of the device. | +| Zimperium.Device.os.id | Number | The operating system identifier of the device. | +| Zimperium.Device.os.maxOsVersion | String | The maximum operating system version of the device. | +| Zimperium.Device.os.name | String | The operating system name. | +| Zimperium.Device.os.osVersionId | Number | The operating system version identifier of the device. | +| Zimperium.Device.os.policyCompliant | Boolean | Whether the operating system policy is compliant in the device. | +| Zimperium.Device.os.type | String | The operating system type of the device. | +| Zimperium.Device.os.version | String | The operating system version of the device. | +| Zimperium.Device.processed | Boolean | Whether the device is processed. | +| Zimperium.Device.processedAt | Date | The date and time that the device was processed. | +| Zimperium.Device.riskPosture | Number | The risk posture of the device. | +| Zimperium.Device.riskPostureName | String | The risk posture name of the device. | +| Zimperium.Device.teamId | String | The team ID of the device. | +| Zimperium.Device.teamName | String | The team name of the device. | +| Zimperium.Device.threatState | Unknown | The threat state information. | +| Zimperium.Device.zappInstance.agentType | Number | The agent type of the device. | +| Zimperium.Device.zappInstance.buildNumber | String | The build number of the zappInstance. | +| Zimperium.Device.zappInstance.bundleId | String | The bundle identifier of the zappInstance. | +| Zimperium.Device.zappInstance.groupId | String | The Zimperium device group identifier for the zappInstance. | +| Zimperium.Device.zappInstance.id | String | The ID of the zappInstance. | +| Zimperium.Device.zappInstance.lastSeen | Date | The last seen timestamp for the zappInstance. | +| Zimperium.Device.zappInstance.name | String | The name of the zappInstance. | +| Zimperium.Device.zappInstance.policiesInfo | String | The policies information. | +| Zimperium.Device.zappInstance.version | String | The version of the zappInstance. | +| Zimperium.Device.zappInstance.zappId | String | The ID of the zappInstance. | +| Zimperium.Device.zappInstance.zbuildNumber | String | The Zimperium device's zappInstance. | +| Zimperium.Device.zappInstance.zversion | String | The device's zappInstance version. | +| Zimperium.Device.zdeviceId | String | The zdevice ID. | +| Zimperium.Device.appVersions.appVersionId | String | The app version ID of the device. | +| Zimperium.Device.appVersions.bundleId | String | The bundle identifier of the app versions. | +| Zimperium.Device.os.maxOsPatchDate | String | The max patch date of operating system of the device. | +| Zimperium.Device.os.patchDate | Date | The operating system patch date of the device. | +| Zimperium.Device.threatState.numberOfCriticalThreats | Number | The number of critical threats detected on the device. | +| Zimperium.Device.zappInstance.permissionsState | Unknown | The permissions state on the device. | +| Zimperium.Device.dormancyProcessed | Boolean | The device's dormancy processed status. | +| Zimperium.Device.os.versionUpgradeable | Boolean | The operating system version upgradeable for the device. | +| Zimperium.Device.threatState | Unknown | The threat state of the device. | +| Zimperium.Device.zappInstance.policiesInfo | Unknown | The device policies info. | +| Zimperium.Device.isJailbroken | Boolean | Whether the endpoint's device is jailbroken or not. | + +#### Command example +```!zimperium-devices-search device_id="5"``` +#### Context Example +```json +{ + "Zimperium": { + "Device": { + "accountId": "2", + "additionalDeviceInfo": [], + "agentType": 2, + "appStatus": "ACTIVE", + "appVersions": [], + "bundleId": "com.zimperium", + "created": 1703082619686, + "deleted": false, + "developerOptionsOn": true, + "deviceOwner": { + "email": "email" + }, + "dormancyProcessed": false, + "fullType": "iPhone14,5", + "groupId": "1", + "id": "5", + "lastSeen": 1703083587626, + "lockScreenUnprotected": true, + "model": "iphone145", + "os": { + "id": 2, + "maxOsVersion": "17.2", + "name": "ios", + "osVersionId": 57106, + "policyCompliant": false, + "type": "iOS", + "version": "16.3", + "versionUpgradeable": true + }, + "processed": true, + "processedAt": 1703082624526, + "riskPosture": 2, + "riskPostureName": "ELEVATED", + "teamId": "1", + "teamName": "Default", + "threatState": { + "addOrRemoveCritical": false, + "addOrRemoveRisky": false, + "criticalThreats": [], + "hadCriticalMitigation": false, + "hadRiskyMitigation": false, + "numberOfRiskyThreats": 5, + "riskyThreats": [ + "5" + ] + }, + "zappInstance": [ + { + "agentType": 2, + "buildNumber": "202", + "bundleId": "com.zimperium", + "externalTrackingId1": "", + "externalTrackingId2": "", + "groupId": "1", + "id": "3", + "lastSeen": 1703083587626, + "name": "MTD", + "policiesInfo": [ + + { + "deployedAt": 1702300970000, + "downloadedAt": 1703082621000, + "hash": "0d", + "type": "Threat iOS" + } + ], + "serverlessDetection": false, + "version": "5.2.16", + "zappId": "c2", + "zbuildNumber": "202", + "zversion": "5.2.16" + } + ], + "zdeviceId": "AF" + } + } +} +``` + +#### Human Readable Output + +>### Device Search Results +>|Risk Posture Name|Id|Model|Os|Bundle Id|Last Seen| +>|---|---|---|---|---|---| +>| ELEVATED | 5 | iphone145 | id: 2
    name: ios
    type: iOS
    version: 16.3
    versionUpgradeable: true
    maxOsVersion: 17.2
    osVersionId: 57106
    policyCompliant: false | com.zimperium | 2023-12-20 14:46:27 | + + +### zimperium-report-get + +*** +Gets a report. + +#### Base Command + +`zimperium-report-get` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- |------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- | +| importance | The importance of the threat. Possible values are: Low, Medium, High, All. Default is High. | Optional | +| app_version_id | The ID of the app version for which to get a JSON report. Can be retrieved using the zimperium-app-version-list command, in the field "Zimperium.AppVersion.id". | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.Report.ContentInformation | String | The content of the report. | +| Zimperium.Report.glob | Number | The glob pattern for the Zimperium report. | +| Zimperium.Report.platform | String | The platform on which the report was created. | +| Zimperium.Report.report.androidAnalysis | String | The android analysis of the report. | +| Zimperium.Report.report.appProperties | String | The app properties. | +| Zimperium.Report.report.certificate | String | The certificate. | +| Zimperium.Report.report.communications | String | The communications. | +| Zimperium.Report.report.contentInformation | String | The content information of the report. | +| Zimperium.Report.report.distribution | String | The report distribution. | +| Zimperium.Report.report.jsonVersion | String | The JSON version of the report. | +| Zimperium.Report.report.riskProfile | String | The risk profile. | +| Zimperium.Report.report.scanDetails | Unknown | The description of the scan details for the report. | +| Zimperium.Report.report.scanVersion | Unknown | The scan version of the Zimperium report. | +| Zimperium.Report.report.vulnerabilities | Unknown | The vulnerabilities found in the report. | +| Zimperium.Report.result | Number | The Zimperium report result. | + +#### Command example +```!zimperium-report-get app_version_id="61" importance="Low"``` +#### Context Example +```json +{ + "Zimperium": { + "Report": { + "ContentInformation": "Copyright 2024 Zimperium", + "glob": 1, + "platform": "android", + "report": { + "androidAnalysis": {}, + "appProperties": { + "extra": { + "itunesAppID": "" + }, + "md5": "1", + "name": "Name", + "packageName": "com.url", + "packageSize": 101918436, + "platform": "android", + "sdkVersion": 22, + "sha1": "1", + "sha256": "1", + "version": "2.12.0", + "versionCode": "1" + }, + "certificate": { + "SHA1 fingerprint": "1", + "SHA256 fingerprint": "1", + "issuer": { + "CN": "CN", + "O": "O" + }, + "owner": { + "CN": "CN", + "O": "O" + } + }, + "contentInformation": { + "copyright": "Copyright 2024 Zimperium" + }, + "distribution": { + "marketData": [] + }, + "jsonVersion": "https://json-schema.org/draft/2020-12/schema", + "riskProfile": { + "malwareDetection": "", + "malwareFamily": "", + "malwareName": "", + "overallRisk": "High", + "privacyRisk": 30, + "securityRisk": 79 + }, + "scanDetails": [ + { + "compliance": [], + "description": "The app is using unity", + "importance": "Low", + "kind": "Code Analysis", + "location": [], + "riskType": "security" + } + ], + "scanVersion": { + "dynamicScan": false, + "ruleVersion": "1", + "scanDateTime": "2023-12-19T18:49:01+0000", + "scanEngine": "2.6.7", + "scanSucces": "Done", + "scanTargetOS": "android", + "scoreDateTime": "2023-12-19T18:49:00+0000" + }, + "vulnerabilities": {} + }, + "result": 1 + } + } +} +``` + +#### Human Readable Output + +>### Report +>|Risk Type|Kind|Description|Location|Importance| +>|---|---|---|---|---| +>| security | Code Analysis | The app is using unity | | Low | +>| privacy | Capabilities | This app implements the SDK. This SDK has functionality that could create screenshots or screen recordings and potentially send them off device too an external resource. | com.sdk | Low | +>| privacy | Backup | This app has disabled the backup feature in Android. This can assist in protecting sensitive information from being exposed in the backup location. | | Low | + + + +#### Base Command + +`zimperium-threat-search` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| after | The date in the criteria after which the threat occurred. | Required | +| before | The date in the criteria before which the threat occurred. | Optional | +| search_params | A comma-separated list of parameter and their values by which to filter your request. For example: 'device.os.version=7.1.1,vectorName=Device'. The parameters table is available under "Threat API Details" section in the "Threats" section, of the Zimperium API documentation, or on the website at https://mtduat.zimperium.com/ziap-docs/zips-docs/api/api_details_threat.html#optional-search-parameters-supported.| Optional | +| team_id | Used to filter the user data by the team the user belongs to. | Optional | +| os | Used to filter by the operating system. Possible values are: ios, android. | Optional | +| severity | The severity of the threat. Possible values are: LOW, NORMAL, ELEVATED, CRITICAL. | Optional | +| page_size | Maximum number of results to retrieve in each page. If a limit is not provided, default is 50. | Optional | +| page | Page number. Default is 0. | Optional | +| limit | Number of total results to return. Default is 50. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.Threat.id | String | The ID of the threat. | +| Zimperium.Threat.accountId | String | The account identifier of the threat. | +| Zimperium.Threat.activationName | String | The activation name of the threat. | +| Zimperium.Threat.agentType | Number | The agent type for the threat. | +| Zimperium.Threat.arpTablesInfo | Unknown | The ARP tables information for the devices. | +| Zimperium.Threat.categoryId | Number | The category of the threat. | +| Zimperium.Threat.classification | Number | The classification of the threat. | +| Zimperium.Threat.classificationName | String | The classification name for the threat. | +| Zimperium.Threat.detectionFiles | Unknown | The threat detection files. | +| Zimperium.Threat.device.id | String | The unique identifier of the device. | +| Zimperium.Threat.device.mamDeviceId | String | The mobile application management (MAM) ID of the device. | +| Zimperium.Threat.device.mdmDeviceId | String | The mobile device management (MDM) ID of the device. | +| Zimperium.Threat.device.model | String | The model of the device the threat was detected on. | +| Zimperium.Threat.device.os.id | Number | The operating system identifier of the device the threat was detected on. | +| Zimperium.Threat.device.os.name | String | The operating system name for the device. | +| Zimperium.Threat.device.os.version | String | The operating system version of the device. | +| Zimperium.Threat.device.zdeviceId | String | The zDevice ID of the device. | +| Zimperium.Threat.deviceId | String | The unique identifier of the device the threat was detected on. | +| Zimperium.Threat.deviceOwner | String | The owner of the device. | +| Zimperium.Threat.eventProcessedTimestamp | Date | The timestamp when the threat event was processed. | +| Zimperium.Threat.eventReceivedTimestamp | Date | The timestamp when the threat event was received. | +| Zimperium.Threat.generalInfo.actionTriggered | String | The threat action triggered on a threat. | +| Zimperium.Threat.generalInfo.bssid | String | The Basic Service Set Identifier (BSSID) of the threat. | +| Zimperium.Threat.generalInfo.deviceTimestamp | Date | The timestamp of the endpoint's device. | +| Zimperium.Threat.generalInfo.jailbreakReasons | String | The jailbreak reasons for the threat. | +| Zimperium.Threat.generalInfo.ssid | String | The service set identifier (SSID) for the threat. | +| Zimperium.Threat.generalInfo.timeInterval | Number | The time interval for a threat. | +| Zimperium.Threat.groupId | String | The ID of the threat group. | +| Zimperium.Threat.lastModified | Date | The time the threat was last modified. | +| Zimperium.Threat.mitigationEvents | Unknown | The mitigation events for the threat. | +| Zimperium.Threat.nearByNetworks | Unknown | The nearby networks for the threat. | +| Zimperium.Threat.networkStatistics | Unknown | The Zimperium threat network statistics. | +| Zimperium.Threat.os | String | The operating system. | +| Zimperium.Threat.policiesInfo.deployedAt | Date | The date that the threat policy was deployed. | +| Zimperium.Threat.policiesInfo.downloadedAt | Date | The date when the threat policy was downloaded. | +| Zimperium.Threat.policiesInfo.hash | String | The hash of the threat policy information. | +| Zimperium.Threat.policiesInfo.type | String | The threat policy type. | +| Zimperium.Threat.processList.parentProcessId | String | The parent process ID for a threat's process. | +| Zimperium.Threat.processList.processId | String | The process ID for the threat process. | +| Zimperium.Threat.processList.processName | String | The process name for the threat. | +| Zimperium.Threat.processList.service | String | The services associated with the process list. | +| Zimperium.Threat.processList.user | String | The users and processes that are involved in the threat process. | +| Zimperium.Threat.responses.eventId | String | The unique identifier for an event in the threat response. | +| Zimperium.Threat.responses.responseId | Number | The response identifier for a threat's response. | +| Zimperium.Threat.responses.timestamp | Date | The timestamp of the threat response. | +| Zimperium.Threat.runningServices | Unknown | The running services. | +| Zimperium.Threat.severity | Number | The severity of the threat. | +| Zimperium.Threat.severityName | String | The severity name of the threat. | +| Zimperium.Threat.simulated | Boolean | Is the threat simulated. | +| Zimperium.Threat.state | Number | The threat state. | +| Zimperium.Threat.suspiciousUrlInfo | Unknown | The suspicious URL information. | +| Zimperium.Threat.teamId | String | The ID of the threat team for an incident. | +| Zimperium.Threat.teamName | String | The threat team name for the Incident. | +| Zimperium.Threat.threatTypeId | Number | The threat type identifier for the threat. | +| Zimperium.Threat.threatTypeName | String | The threat type for the threat. | +| Zimperium.Threat.timestamp | Date | The timestamp of the threat. | +| Zimperium.Threat.timestampInfo | Unknown | The timestamp information of the threat. | +| Zimperium.Threat.vector | Number | The threat vector for the incident. | +| Zimperium.Threat.vectorName | String | The vector name for a threat. | +| Zimperium.Threat.zappId | String | The Zimperium threat app identifier. | +| Zimperium.Threat.zappInstance | Unknown | The threat Zapp instance information. | +| Zimperium.Threat.zappInstanceId | String | The Zapp threat instance ID. | +| Zimperium.Threat.zeventId | String | The Zimperium threat event identifier. | +| Zimperium.Threat.arpTablesInfo | Unknown | The ARP tables info for the threat. | +| Zimperium.Threat.locationInfo.geoPoint.lat | Number | The latitude of the geoPoint. | +| Zimperium.Threat.locationInfo.geoPoint.lon | Number | The longitude of the geoPoint. | +| Zimperium.Threat.locationInfo.source | String | The threat's source location information. | +| Zimperium.Threat.generalInfo.expectedOsVersion | String | The expected operating system version for the threat. | +| Zimperium.Threat.generalInfo.vulnerableOsVersion | String | The vulnerable operating system version for the threat. | +| Zimperium.Threat.generalInfo.vulnerableSecurityPatch | String | The vulnerable security patch for the endpoint. | +| Zimperium.Threat.mitigatedAt | Date | The date when the Threat was mitigated. | + +#### Command example +```!zimperium-threat-search after="3 month" team_id="33" limit=1``` +#### Context Example +```json +{ + "Zimperium": { + "Threat": { + "accountId": "25", + "activationName": "user@email.com", + "agentType": 2, + "arpTablesInfo": { + "before": [ + { + "ip": "1.1.1.1", + "mac": "1.1.1.1" + } + ] + }, + "categoryId": 15, + "classification": 1, + "classificationName": "CRITICAL", + "detectionFiles": [], + "device": { + "id": "6", + "mamDeviceId": "", + "mdmDeviceId": "", + "model": "ONEPLUS A5000", + "os": { + "id": 1, + "name": "ANDROID", + "version": "7.1.1" + }, + "zdeviceId": "5" + }, + "deviceId": "6", + "deviceOwner": "user@email.com", + "eventProcessedTimestamp": 1702393167374, + "eventReceivedTimestamp": 1702393167359, + "generalInfo": { + "actionTriggered": "Silent Alert", + "deviceTimestamp": 1702393165000, + "jailbreakReasons": "SELinux disabled", + "timeInterval": 8 + }, + "groupId": "37", + "id": "d7", + "lastModified": 1702393165000, + "mitigationEvents": [], + "nearByNetworks": [], + "networkStatistics": [], + "os": "android", + "policiesInfo": [ + { + "deployedAt": 1701806956000, + "downloadedAt": 1702393157000, + "type": "App Policy Android v2" + } + ], + "processList": [ + { + "parentProcessId": "1585", + "processId": "7839", + "processName": "com.zimperium", + "service": "n/a", + "user": "1" + } + ], + "responses": [ + { + "eventId": "1", + "responseId": 3, + "timestamp": 1702393165000 + } + ], + "runningServices": [], + "severity": 3, + "severityName": "CRITICAL", + "simulated": false, + "state": 1, + "suspiciousUrlInfo": {}, + "teamId": "33", + "teamName": "Default", + "threatTypeId": 37, + "threatTypeName": "SYSTEM TAMPERING", + "timestamp": 1702393165000, + "timestampInfo": { + "timestamp": 1702393165000, + "toTheDay": 1702339200000, + "toTheHour": 1702389600000, + "toTheMinute": 1702393140000, + "toTheSecond": 1702393165000 + }, + "vector": 2, + "vectorName": "Device", + "zappId": "40", + "zappInstance": { + "buildNumber": "230829190", + "bundleId": "com.zimperium", + "id": "63", + "name": "MTD", + "version": "5.2.14", + "zbuildNumber": "23082919", + "zversion": "5.2.14" + }, + "zappInstanceId": "63", + "zeventId": "a1" + } + } +} +``` + +#### Human Readable Output + +>### Threat Search Result +>|Id|Severity Name|State|Vector Name|Threat Type Name|Os|Device Owner|Device Id|Team Name|Timestamp| +>|---|---|---|---|---|---|---|---|---|---| +>| d7 | CRITICAL | 1 | Device | SYSTEM TAMPERING | android | user@email.com | 6 | Default | 2023-12-12 14:59:25 | + + + +### zimperium-app-version-list + +*** +List the app versions. + +#### Base Command + +`zimperium-app-version-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| bundle_id | The bundle ID of the app for which to get its app version. | Optional | +| page_size | Maximum number of results to retrieve in each page. If a limit is not provided, default is 50. | Optional | +| page | Page number. Default is 0. | Optional | +| limit | Number of total results to return. Default is 50. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.AppVersion.id | String | The ID of the threat. | +| Zimperium.AppVersion.accountId | String | The account identifier for the Zimperium app version. | +| Zimperium.AppVersion.bundleId | String | The bundle identifier for the Zimperium app version. | +| Zimperium.AppVersion.classification | String | The classification of the Zimperium app version. | +| Zimperium.AppVersion.created | Date | When the app version was created. | +| Zimperium.AppVersion.hash | String | The hash of the Zimperium app version. | +| Zimperium.AppVersion.name | String | The name of the Zimperium app version. | +| Zimperium.AppVersion.platform | String | The platform on which the Zimperium app version is running. | +| Zimperium.AppVersion.platformId | Number | The platform identifier for the Zimperium app version. | +| Zimperium.AppVersion.privacy | String | The privacy setting for the app version. | +| Zimperium.AppVersion.privacyRisk | Number | The privacy risk for the Zimperium app version. | +| Zimperium.AppVersion.processState | String | The process state of the app version. | +| Zimperium.AppVersion.reportRequestId | String | The Zimperium app version report request ID. | +| Zimperium.AppVersion.riskVersion | String | The risk version of the Zimperium app version. | +| Zimperium.AppVersion.security | String | The security of the Zimperium app version. | +| Zimperium.AppVersion.securityRisk | Number | The security risk of the Zimperium app version. | +| Zimperium.AppVersion.source | String | The Zimperium app version source. | +| Zimperium.AppVersion.updatedOn | Date | The date and time when the app version was updated. | +| Zimperium.AppVersion.version | String | The version of the Zimperium app version. | +| Zimperium.AppVersion.developerName | String | The developer name for the Zimperium app version. | +| Zimperium.AppVersion.developerSignature | String | The developer signature for the Zimperium app version. | +| Zimperium.AppVersion.filename | String | The filename of the Zimperium app version. | +| Zimperium.AppVersion.managed | Boolean | Whether the app version is managed. | + +#### Command example +```!zimperium-app-version-list bundle_id="com.url"``` +#### Context Example +```json +{ + "Zimperium": { + "AppVersion": [ + { + "accountId": "2", + "bundleId": "com.url", + "classification": "LEGIT", + "created": 1702304668599, + "hash": "E3", + "id": "7", + "name": "Name", + "platform": "android", + "platformId": 1, + "privacy": "Low", + "privacyRisk": 30, + "processState": "AVAILABLE", + "reportRequestId": "E3", + "riskVersion": "2.12.0", + "security": "High", + "securityRisk": 79, + "source": "UPLOAD", + "updatedOn": 1702308488217, + "version": "2.12.0" + }, + { + "accountId": "2", + "bundleId": "com.url", + "classification": "LEGIT", + "created": 1702305485276, + "developerName": "TShih", + "developerSignature": "02", + "filename": "/tmp/sample", + "hash": "04", + "id": "61", + "managed": false, + "name": "Name", + "platform": "android", + "platformId": 1, + "privacy": "Low", + "privacyRisk": 30, + "processState": "AVAILABLE", + "riskVersion": "2.12.0", + "security": "High", + "securityRisk": 79, + "source": "GLOBAL", + "updatedOn": 1702308488294, + "version": "2.12.0" + } + ] + } +} +``` + +#### Human Readable Output + +>### App Version List +>|Id|Name|Bundle Id|Version|Platform|Security|Privacy|Classification|Developer Name|Created|Updated On| +>|---|---|---|---|---|---|---|---|---|---|---| +>| 7 | Name | com.url | 2.12.0 | android | High | Low | LEGIT | | 2023-12-11 14:24:28 | 2023-12-11 15:28:08 | +>| 61 | Name | com.url | 2.12.0 | android | High | Low | LEGIT | TShih | 2023-12-11 14:38:05 | 2023-12-11 15:28:08 | + + +### zimperium-get-devices-by-cve + +*** +Gets a devices associated with a specific CVE. + +#### Base Command + +`zimperium-get-devices-by-cve` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| cve_id | The ID of the CVE which is input. | Required | +| after | The date in the criteria after which the threat occurred. | Optional | +| before | The date in the criteria before which the threat occurred. | Optional | +| team_id | Used to filter the user data by the team the user belongs to. | Optional | +| page_size | Maximum number of results to retrieve in each page. If a limit is not provided, default is 50. | Optional | +| page | Page number. Default is 0. | Optional | +| limit | Number of total results to return. Default is 50. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +|---------------------------------------------| --- |-------------------------------------------------------------------| +| Zimperium.DeviceByCVE.id | String | The ID of the device. | +| Zimperium.DeviceByCVE.cveId | String | The ID of the CVE. | +| Zimperium.DeviceByCVE.os.id | Number | The operating system identifier of the device. | +| Zimperium.DeviceByCVE.os.maxOsPatchDate | String | The device operating system max patch date. | +| Zimperium.DeviceByCVE.os.maxOsVersion | String | The device operating system max version. | +| Zimperium.DeviceByCVE.os.name | String | The operating system name of the device. | +| Zimperium.DeviceByCVE.os.osVersionId | Number | The operating system version identifier of the device. | +| Zimperium.DeviceByCVE.os.patchDate | Date | The patch date for of the operating system. | +| Zimperium.DeviceByCVE.os.policyCompliant | Boolean | Whether the operating system policy is compliant with the device. | +| Zimperium.DeviceByCVE.os.type | String | The operating system type of the device. | +| Zimperium.DeviceByCVE.os.version | String | The operating system version of the device. | +| Zimperium.DeviceByCVE.os.versionUpgradeable | Boolean | Whether the operating system version was upgradeable. | +| Zimperium.DeviceByCVE.teamId | String | The team ID of the device. | +| Zimperium.DeviceByCVE.zdeviceId | String | The zdevice ID of the device. | + + +#### Command example +```!zimperium-get-devices-by-cve cve_id="CVE-2021-1886" limit=1``` +#### Context Example +```json +{ + "Zimperium": { + "DeviceCVE": { + "id": "6", + "cveId": "CVE-2021-1886", + "os": { + "id": 1, + "maxOsPatchDate": "20200901", + "maxOsVersion": "10", + "name": "android", + "osVersionId": 57063, + "patchDate": "2017-09-01", + "policyCompliant": false, + "type": "Android", + "version": "7.1.1", + "versionUpgradeable": true + }, + "teamId": "33", + "zdeviceId": "5" + } + } +} +``` + +#### Human Readable Output + +>### Devices Associated with CVE-2021-1886 +>|Id|Zdevice Id|Team Id|Os| +>|---|---|---|---| +>| 6 | 5 | 33 | id: 1
    name: android
    type: Android
    version: 7.1.1
    patchDate: 2017-09-01
    versionUpgradeable: true
    maxOsVersion: 10
    maxOsPatchDate: 20200901
    osVersionId: 57063
    policyCompliant: false | + + +### zimperium-devices-os-version + +*** +Gets devices associated with a specific operating system version. + +#### Base Command + +`zimperium-devices-os-version` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| os_version | The name of the version which is input. Can be retrieved using zimperium-devices-search command under "Zimperium.Device.os.version". | Required | +| os_patch_date | The date of the patch for a specific version. The date format is YYYY-MM-DD. This field is only applicable to Android. If you include this field, only CVEs for Android are returned since this value does not apply to iOS. | Optional | +| deleted | This is used to request the devices that have been deleted. Possible values are: true, false. | Optional | +| after | The date in the criteria after which the threat occurred. | Optional | +| before | The date in the criteria before which the threat occurred. | Optional | +| team_id | This is used to filter the data to their respective teams. | Optional | +| page_size | Maximum number of results to retrieve in each page. If a limit is not provided, default is 50. | Optional | +| page | Page number. Default is 0. | Optional | +| limit | Number of total results to return. Default is 50. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.DeviceOsVersion.id | String | The ID of the device. | +| Zimperium.DeviceOsVersion.os.id | Number | The operating system identifier of the device. | +| Zimperium.DeviceOsVersion.os.maxOsPatchDate | String | The device operating system max patch date. | +| Zimperium.DeviceOsVersion.os.maxOsVersion | String | The device operating system max version. | +| Zimperium.DeviceOsVersion.os.name | String | The operating system name of the device. | +| Zimperium.DeviceOsVersion.os.osVersionId | Number | The operating system version identifier of the device. | +| Zimperium.DeviceOsVersion.os.patchDate | Date | The patch date of the device's operating system. | +| Zimperium.DeviceOsVersion.os.policyCompliant | Boolean | Whether the endpoint's operating system is compliant with the policy. | +| Zimperium.DeviceOsVersion.os.type | String | The operating system type. | +| Zimperium.DeviceOsVersion.os.version | String | The operating system version. | +| Zimperium.DeviceOsVersion.os.versionUpgradeable | Boolean | Whether the device's operating system is upgradeable. | +| Zimperium.DeviceOsVersion.teamId | String | The team ID of the device. | +| Zimperium.DeviceOsVersion.zdeviceId | String | The zdevice ID of the device. | + +#### Command example +```!zimperium-devices-os-version os_version="9"``` +#### Context Example +```json +{ + "Zimperium": { + "DeviceOsVersion": { + "id": "2a", + "os": { + "id": 1, + "maxOsPatchDate": "20230501", + "maxOsVersion": "13", + "name": "android", + "osVersionId": 57062, + "patchDate": "2019-08-05", + "policyCompliant": false, + "type": "Android", + "version": "9", + "versionUpgradeable": true + }, + "teamId": "1", + "zdeviceId": "a8" + } + } +} +``` + +#### Human Readable Output + +>### Device Os Version +>|Id|Team Id|Os| +>|---|---|---| +>| 2a | 1 | id: 1
    name: android
    type: Android
    version: 9
    patchDate: 2019-08-05
    versionUpgradeable: true
    maxOsVersion: 13
    maxOsPatchDate: 20230501
    osVersionId: 57062
    policyCompliant: false | + + +### zimperium-get-cves-by-device + +*** +Gets the CVEs associated with a specific device. + +#### Base Command + +`zimperium-get-cves-by-device` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| device_id | The device ID to get CVEs for. | Required | +| page_size | Maximum number of results to retrieve in each page. If a limit is not provided, default is 50. | Optional | +| page | Page number. Default is 0. | Optional | +| limit | Number of total results to return. Default is 50. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- |--------------------------------------| +| Zimperium.CVEByDevice.id | String | The ID of the CVE. | +| Zimperium.CVEByDevice.deviceId | String | The ID of the device. | +| Zimperium.CVEByDevice.activeExploit | Boolean | Whether the CVE is active or not. | +| Zimperium.CVEByDevice.exploitPocUrl.exploitPocUrls | Unknown | The exploit POC URLs for the CVE. | +| Zimperium.CVEByDevice.severity | String | The severity of a CVE on the device. | +| Zimperium.CVEByDevice.type | String | The CVE type. | +| Zimperium.CVEByDevice.url | String | The URL of the CVE. | + +#### Command example +```!zimperium-get-cves-by-device device_id="2a"``` +#### Context Example +```json +{ + "Zimperium": { + "CVEDevice": [ + { + "activeExploit": false, + "exploitPocUrl": { + "exploitPocUrls": [] + }, + "id": "CVE-2019-2173", + "severity": "High", + "type": "Elevation of privilege", + "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2173", + "deviceId": "2a" + }, + { + "activeExploit": false, + "exploitPocUrl": { + "exploitPocUrls": [] + }, + "id": "CVE-2019-2176", + "severity": "Critical", + "type": "Remote code execution", + "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2176", + "deviceId": "2a" + } + ] + } +} +``` + +#### Human Readable Output + +>### CVE on Device 2a +>|Id|Type|Severity|Url|Active Exploit|Exploit Poc Url| +>|---|---|---|---|---|---| +>| CVE-2019-2173 | Elevation of privilege | High | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2173 | false | exploitPocUrls: | +>| CVE-2019-2176 | Remote code execution | Critical | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2176 | false | exploitPocUrls: | + + +### zimperium-vulnerability-get + +*** +Gets the vulnerabilities. + +#### Base Command + +`zimperium-vulnerability-get` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| page_size | Maximum number of results to retrieve in each page. If a limit is not provided, default is 50. | Optional | +| page | Page number. Default is 0. | Optional | +| limit | Number of total results to return. Default is 50. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.Vulnerability.id | String | The ID of the vulnerability. | +| Zimperium.Vulnerability.blueBorneVulnerable | Boolean | Whether the operating system is blue born vulnerable. | +| Zimperium.Vulnerability.cveCount | Number | Number of CVEs on the operating system. | +| Zimperium.Vulnerability.lastCveSync | Date | The date of the last CVE sync. | +| Zimperium.Vulnerability.os | Number | The vulnerability operating system. | +| Zimperium.Vulnerability.osPatchDate | Unknown | The max patch date of operating system. | +| Zimperium.Vulnerability.osRiskChecksum | String | The operating system risk checksum. | +| Zimperium.Vulnerability.osVersion | String | The operating system version. | +| Zimperium.Vulnerability.osVersionAndPatchDate | String | The operating system version and the patch date. | +| Zimperium.Vulnerability.risk | String | The risk classification. | + + +#### Command example +```!zimperium-vulnerability-get limit=1``` +#### Context Example +```json +{ + "Zimperium": { + "Vulnerability": { + "blueBorneVulnerable": false, + "cveCount": 432, + "id": 56745, + "lastCveSync": 1707218387516, + "os": 2, + "osPatchDate": null, + "osRiskChecksum": "6A", + "osVersion": "14.6", + "osVersionAndPatchDate": "14.6", + "risk": "Critical" + } + } +} +``` + +#### Human Readable Output + +>### Vulnerabilities List +>|Id|Os|Os Version And Patch Date|Os Version|Os Patch Date|Risk|Cve Count|Last Cve Sync|Os Risk Checksum|Blue Borne Vulnerable| +>|---|---|---|---|---|---|---|---|---|---| +>| 56745 | 2 | 14.6 | 14.6 | | Critical | 432 | 2024-02-06 11:19:47 | 6A | false | + + + +### zimperium-policy-group-list + +*** +Get policy groups. + +#### Base Command + +`zimperium-policy-group-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| module | The module parameter is required to get the groups related to EMM connection or ZIPS connection. Default is "ZIPS". Possible values are: EMM, ZIPS. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.PolicyGroup.id | String | The ID of the policy group. | +| Zimperium.PolicyGroup.accountId | String | The account identifier for the policy group's content. | +| Zimperium.PolicyGroup.appPolicyId | String | The app policy ID of the policy group. | +| Zimperium.PolicyGroup.appSettingsId | String | The app settings ID of the policy group. | +| Zimperium.PolicyGroup.brandingPolicyId | Unknown | The branding policy identifier of the policy group. | +| Zimperium.PolicyGroup.created | Date | The date and time the policy group was created. | +| Zimperium.PolicyGroup.description | String | The description of the policy group. | +| Zimperium.PolicyGroup.dormancyPolicyId | String | The dormancy policy identifier of the policy group. | +| Zimperium.PolicyGroup.emmConnectionId | Unknown | The enterprise mobile management (EMM) connection ID of the policy group. | +| Zimperium.PolicyGroup.emmGroupId | Unknown | The enterprise mobile management (EMM) group ID of the policy group. | +| Zimperium.PolicyGroup.emmPriority | Unknown | The enterprise mobile management (EMM) priority of the policy group. | +| Zimperium.PolicyGroup.extensionPolicyId | String | The extension policy identifier of the policy group. | +| Zimperium.PolicyGroup.content.global | Boolean | Whether the policy group is global. | +| Zimperium.PolicyGroup.knoxPolicyId | Unknown | The Knox policy ID of the policy group. | +| Zimperium.PolicyGroup.modified | Date | The date and time when the policy group was last modified. | +| Zimperium.PolicyGroup.name | String | The name of the policy group. | +| Zimperium.PolicyGroup.networkPolicyId | String | The network policy ID of the policy group. | +| Zimperium.PolicyGroup.osRiskPolicyId | String | The operating system risk policy ID of the policy group. | +| Zimperium.PolicyGroup.phishingPolicyId | String | The phishing policy identifier of the policy group. | +| Zimperium.PolicyGroup.privacyId | String | The privacy identifier of the policy group. | +| Zimperium.PolicyGroup.team.id | String | The ID of the team associated with the policy group. | +| Zimperium.PolicyGroup.team.name | String | The team name of the policy group. | +| Zimperium.PolicyGroup.trmId | String | The Threat Response Matrix (TRM) ID of the policy group. | +| Zimperium.PolicyGroup.team | Unknown | The policy group's team information. | + +#### Command example +```!zimperium-policy-group-list``` +#### Context Example +```json +{ + "Zimperium": { + "PolicyGroup": [ + { + "accountId": "2", + "appPolicyId": "2", + "appSettingsId": "a5", + "brandingPolicyId": null, + "created": "2024-01-22T11:37:36.749+00:00", + "description": "test", + "dormancyPolicyId": "2", + "emmConnectionId": null, + "emmGroupId": null, + "emmPriority": null, + "extensionPolicyId": "2", + "global": false, + "id": "65", + "knoxPolicyId": null, + "modified": "2024-01-22T11:37:36.749+00:00", + "name": "Test", + "networkPolicyId": "2", + "osRiskPolicyId": "2", + "phishingPolicyId": "2", + "privacyId": "a2", + "team": { + "id": "1", + "name": "Default" + }, + "trmId": "er" + } + ] + } +} +``` + +#### Human Readable Output + +>### Policy Group List +>|Id|Name|Team|Privacy Id|Trm Id|Phishing Policy Id|App Settings Id|App Policy Id|Network Policy Id|Os Risk Policy Id| +>|---|---|---|---|---|---|---|---|---|---| +>| 65 | Test | id: 1
    name: Default | a2 | er | 2 | a5 | 2 | 2 | 2 | + + +### zimperium-policy-privacy-get + +*** +Get a privacy policy by its identifier. + +#### Base Command + +`zimperium-policy-privacy-get` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| policy_id | The identifier of the policy. Can be retrieved using zimperium-policy-group-list in the Zimperium.PolicyGroup.privacyId field. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.PolicyPrivacy.id | String | The policy privacy identifier. | +| Zimperium.PolicyPrivacy.accountId | String | The account identifier of the policy. | +| Zimperium.PolicyPrivacy.assigned | Boolean | Whether the policy privacy is assigned. | +| Zimperium.PolicyPrivacy.created | Date | The date and time the policy was created. | +| Zimperium.PolicyPrivacy.global | Boolean | Whether the policy settings are global. | +| Zimperium.PolicyPrivacy.groups | String | The groups the policy are associated with. | +| Zimperium.PolicyPrivacy.jsonHash | String | The JSON hash for the policy privacy policy. | +| Zimperium.PolicyPrivacy.locationAccuracy | Number | The location accuracy for the policy. | +| Zimperium.PolicyPrivacy.modified | Date | The date and time when the policy was modified. | +| Zimperium.PolicyPrivacy.name | String | The name of the policy. | +| Zimperium.PolicyPrivacy.protoHash | String | The hash of the policy. | +| Zimperium.PolicyPrivacy.rules | Unknown | The policy rules list. | +| Zimperium.PolicyPrivacy.rules.id | String | The ID of the rule. | +| Zimperium.PolicyPrivacy.team | Unknown | The team for the policy. | +| Zimperium.PolicyPrivacy.teamId | Unknown | The team ID the policy is associated with. | + +#### Command example +```!zimperium-policy-privacy-get policy_id="a2"``` +#### Context Example +```json +{ + "Zimperium": { + "PolicyPrivacy": { + "accountId": "2", + "assigned": true, + "created": "2023-12-05T20:09:16.621+00:00", + "global": true, + "groups": [ + { + "accountId": "2", + "created": "2024-01-22T11:37:36.749+00:00", + "description": "test", + "emm": false, + "global": false, + "groupActivations": [], + "id": "65", + "modified": "2024-01-22T11:37:36.749+00:00", + "name": "Test", + "staticFilesWritten": "2024-02-05T06:00:03.460+00:00", + "userActivations": [], + "zapps": [] + }, + { + "accountId": "2", + "created": "2023-12-05T20:09:16.621+00:00", + "description": "Default Group", + "emm": false, + "global": true, + "groupActivations": [], + "id": "37", + "modified": "2023-12-05T20:09:16.621+00:00", + "name": "Default Group", + "staticFilesWritten": "2024-02-06T06:00:37.129+00:00", + "userActivations": [ + { + "id": "40" + } + ], + "zapps": [] + } + ], + "id": "a2", + "jsonHash": "7d", + "locationAccuracy": 0, + "modified": "2023-12-05T20:09:16.853+00:00", + "name": "Default", + "rules": [ + { + "collectibleId": 0, + "id": "3b", + "shouldCollect": false + } + ], + "staticFilesWritten": "2023-12-05T20:09:19.079+00:00", + "team": null, + "teamId": null + } + } +} +``` + +#### Human Readable Output + +>### Privacy Policy +>|Id|Name|Created|Modified| +>|---|---|---|---| +>| a2 | Default | 2023-12-05T20:09:16.621+00:00 | 2023-12-05T20:09:16.853+00:00 | + + +### zimperium-policy-threat-get + +*** +Get a threat policy by its identifier. + +#### Base Command + +`zimperium-policy-threat-get` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| policy_id | The identifier of the policy. Can be retrieved using zimperium-policy-group-list in the Zimperium.PolicyGroup.trmId field. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.PolicyThreat.id | String | The identifier of the policy. | +| Zimperium.PolicyThreat.accountId | String | The account identifier of the policy. | +| Zimperium.PolicyThreat.androidJsonHash | String | The Android JSON hash. | +| Zimperium.PolicyThreat.androidProtoHash | String | The Android Proto hash. | +| Zimperium.PolicyThreat.assigned | Boolean | Whether the policy is assigned. | +| Zimperium.PolicyThreat.created | Date | The date and time the policy threat was created. | +| Zimperium.PolicyThreat.deploymentDate | Date | The date when the policy deployment occurred. | +| Zimperium.PolicyThreat.global | Boolean | Whether the policy settings are global. | +| Zimperium.PolicyThreat.groups | Unknown | The groups the policy are associated with. | +| Zimperium.PolicyThreat.iosJsonHash | String | IOS JSON hash. | +| Zimperium.PolicyThreat.iosProtoHash | String | IOS Proto hash. | +| Zimperium.PolicyThreat.isDeployed | Boolean | Whether the policy threat is deployed or not. | +| Zimperium.PolicyThreat.modified | Date | The date and time when the policy was modified. | +| Zimperium.PolicyThreat.name | String | The name of the policy. | +| Zimperium.PolicyThreat.rules | Unknown | The policy rules list. | +| Zimperium.PolicyThreat.rules.id | String | The ID of the policy rule. | + +#### Command example +```!zimperium-policy-threat-get policy_id="er"``` +#### Context Example +```json +{ + "Zimperium": { + "PolicyThreat": { + "accountId": "2", + "androidJsonHash": "eb", + "androidProtoHash": "4f", + "assigned": true, + "created": "2023-12-05T20:09:16.621+00:00", + "deploymentDate": "2023-12-05T20:09:18.474+00:00", + "emm": false, + "global": true, + "groups": [ + { + "accountId": "2", + "created": "2024-01-22T11:37:36.749+00:00", + "description": "test", + "emm": false, + "global": false, + "groupActivations": [], + "id": "65", + "modified": "2024-01-22T11:37:36.749+00:00", + "name": "Test", + "staticFilesWritten": "2024-02-05T06:00:03.460+00:00", + "userActivations": [], + "zapps": [] + }, + { + "accountId": "2", + "created": "2023-12-05T20:09:16.621+00:00", + "description": "Default Group", + "emm": false, + "global": true, + "groupActivations": [], + "id": "37", + "modified": "2023-12-05T20:09:16.621+00:00", + "name": "Default Group", + "staticFilesWritten": "2024-02-06T06:00:37.129+00:00", + "userActivations": [ + { + "id": "40" + } + ], + "zapps": [] + } + ], + "id": "er", + "iosJsonHash": "eb", + "iosProtoHash": "4f", + "isDeployed": true, + "modified": "2023-12-05T20:09:17.184+00:00", + "name": "Default", + "rules": [ + { + "alertUser": false, + "customResponses": [], + "id": "b9", + "legacyMdmMitigationAction": null, + "legacyMdmThreatAction": null, + "mdmMitigationAction": null, + "mdmMitigationTarget": null, + "mdmThreatAction": null, + "mdmThreatTarget": null, + "responses": [], + "severity": 0, + "shouldCollect": true, + "threatTypeId": 0 + } + ], + "staticFilesWritten": "2023-12-05T20:09:18.129+00:00" + } + } +} +``` + +#### Human Readable Output + +>### Threat Policy +>|Id|Is Deployed|Name|Created|Modified| +>|---|---|---|---|---| +>| er | true | Default | 2023-12-05T20:09:16.621+00:00 | 2023-12-05T20:09:17.184+00:00 | + + +### zimperium-policy-phishing-get + +*** +Get a phishing policy by its identifier. + +#### Base Command + +`zimperium-policy-phishing-get` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| policy_id | The identifier of the policy. Can be retrieved using zimperium-policy-group-list in the Zimperium.PolicyGroup.phishingPolicyId field. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.PolicyPhishing.id | String | The identifier of the policy. | +| Zimperium.PolicyPhishing.accessControlList | Unknown | The access control list for the policy resource. | +| Zimperium.PolicyPhishing.accountId | String | The account identifier of the policy. | +| Zimperium.PolicyPhishing.allowEndUserControl | Boolean | Whether the end user is allowed to control the policy. | +| Zimperium.PolicyPhishing.contentCategoryActionList | Unknown | The content of the policy category action. | +| Zimperium.PolicyPhishing.created | Date | The date and time the policy threat was created. | +| Zimperium.PolicyPhishing.enableDnsPhishingTutorial | Boolean | Whether the DNS phishing tutorial is enabled. | +| Zimperium.PolicyPhishing.enableMessageFilterTutorial | Boolean | Whether the message filter tutorial is enabled. | +| Zimperium.PolicyPhishing.enableSafariBrowserExtensionTutorial | Boolean | Whether the Safari Browser Extension tutorial is enabled. | +| Zimperium.PolicyPhishing.global | Boolean | Whether the policy settings are global. | +| Zimperium.PolicyPhishing.groups | Unknown | The groups the policy are associated with. | +| Zimperium.PolicyPhishing.isDnsEnabled | Boolean | Whether DNS is enabled or not. | +| Zimperium.PolicyPhishing.modified | Date | The date and time when the policy was modified. | +| Zimperium.PolicyPhishing.name | String | The name of the policy. | +| Zimperium.PolicyPhishing.phishingDetectionAction | String | The phishing detection action. | +| Zimperium.PolicyPhishing.phishingPolicyType | String | The phishing policy type. | +| Zimperium.PolicyPhishing.team | Unknown | The team the policy is associated with. | +| Zimperium.PolicyPhishing.teamId | Unknown | The ID of the team. | +| Zimperium.PolicyPhishing.useLocalVpn | Boolean | Whether to use a local VPN or not. | +| Zimperium.PolicyPhishing.useRemoteContentInspection | Boolean | Whether to use remote content inspection. | +| Zimperium.PolicyPhishing.useUrlSharing | Boolean | Whether the URL sharing is enabled or not. | + +#### Command example +```!zimperium-policy-phishing-get policy_id="2"``` +#### Context Example +```json +{ + "Zimperium": { + "PolicyPhishing": { + "accessControlList": null, + "accountId": "2", + "allowEndUserControl": false, + "contentCategoryActionList": [], + "created": "2023-12-05T20:09:16.621+00:00", + "enableDnsPhishingTutorial": false, + "enableMessageFilterTutorial": true, + "enableSafariBrowserExtensionTutorial": true, + "global": true, + "groups": [ + { + "accountId": "2", + "created": "2024-01-22T11:37:36.749+00:00", + "description": "test", + "emm": false, + "global": false, + "groupActivations": [], + "id": "65", + "modified": "2024-01-22T11:37:36.749+00:00", + "name": "Test", + "staticFilesWritten": "2024-02-05T06:00:03.460+00:00", + "userActivations": [], + "zapps": [] + }, + { + "accountId": "2", + "created": "2023-12-05T20:09:16.621+00:00", + "description": "Default Group", + "emm": false, + "global": true, + "groupActivations": [], + "id": "37", + "modified": "2023-12-05T20:09:16.621+00:00", + "name": "Default Group", + "staticFilesWritten": "2024-02-06T06:00:37.129+00:00", + "userActivations": [ + { + "id": "40" + } + ], + "zapps": [] + } + ], + "id": "2", + "isDnsEnabled": false, + "modified": "2023-12-11T13:33:08.481+00:00", + "name": "Default", + "phishingDetectionAction": "WARN", + "phishingPolicyType": "ON_DEVICE", + "team": null, + "teamId": null, + "useLocalVpn": true, + "useRemoteContentInspection": true, + "useUrlSharing": true + } + } +} +``` + +#### Human Readable Output + +>### Phishing Policy +>|Id|Name|Created|Modified|Enable Safari Browser Extension Tutorial|Enable Dns Phishing Tutorial|Use Local Vpn|Use Url Sharing|Allow End User Control|Use Remote Content Inspection|Enable Message Filter Tutorial|Phishing Detection Action|Phishing Policy Type| +>|---|---|---|---|---|---|---|---|---|---|---|---|---| +>| 2 | Default | 2023-12-05T20:09:16.621+00:00 | 2023-12-11T13:33:08.481+00:00 | true | false | true | true | false | true | true | WARN | ON_DEVICE | + + +### zimperium-policy-app-settings-get + +*** +List the app versions. + +#### Base Command + +`zimperium-policy-app-settings-get` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| app_settings_policy_id | The identifier of the policy. Can be retrieved using zimperium-policy-group-list in the Zimperium.PolicyGroup.appSettingsId field. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.PolicyAppSetting.id | String | The identifier of the policy. | +| Zimperium.PolicyAppSetting.accountId | String | The account identifier of the policy. | +| Zimperium.PolicyAppSetting.appRiskLookupEnabled | Boolean | Whether the app risk lookup is enabled or not. | +| Zimperium.PolicyAppSetting.assigned | Boolean | Whether the policy is assigned. | +| Zimperium.PolicyAppSetting.autoActivateKnox | Boolean | Whether Knox should be automatically activated. | +| Zimperium.PolicyAppSetting.autoBatteryOptimizationEnabled | Boolean | Whether the battery optimization is enabled. | +| Zimperium.PolicyAppSetting.cogitoEnabled | Boolean | Whether the cogito is enabled. | +| Zimperium.PolicyAppSetting.cogitoThreshold | Number | The cogito threshold. | +| Zimperium.PolicyAppSetting.created | Date | The date and time the policy was created. | +| Zimperium.PolicyAppSetting.dangerzoneEnabled | Boolean | Whether the danger zone is enabled or not. | +| Zimperium.PolicyAppSetting.detectionEnabled | Boolean | Whether detection is enabled. | +| Zimperium.PolicyAppSetting.forensicAnalysisEnabled | Boolean | Whether forensic analysis is enabled. | +| Zimperium.PolicyAppSetting.global | Boolean | Whether the policy is global. | +| Zimperium.PolicyAppSetting.groups | Unknown | The groups information. | +| Zimperium.PolicyAppSetting.jsonHash | String | The JSON hash of the policy. | +| Zimperium.PolicyAppSetting.modified | Date | The modified date of the policy. | +| Zimperium.PolicyAppSetting.name | String | The name of the policy. | +| Zimperium.PolicyAppSetting.phishingEnabled | Boolean | Whether phishing is enabled or not. | +| Zimperium.PolicyAppSetting.phishingLocalClassifierEnabled | Boolean | Whether the phishing local classifier is enabled. | +| Zimperium.PolicyAppSetting.phishingThreshold | Number | The phishing threshold. | +| Zimperium.PolicyAppSetting.privacySummaryEnabled | Boolean | Whether the privacy summary is enabled. | +| Zimperium.PolicyAppSetting.protoHash | String | The proto hash. | +| Zimperium.PolicyAppSetting.siteInsightEnabled | Boolean | Whether the site insight is enabled or not. | +| Zimperium.PolicyAppSetting.staticFilesWritten | Date | The date when the static files were written. | +| Zimperium.PolicyAppSetting.team | Unknown | The team name the policy is associated with. | +| Zimperium.PolicyAppSetting.teamId | Unknown | The ID of the team to which the policy belongs. | + +#### Command example +```!zimperium-policy-app-settings-get app_settings_policy_id="9e"``` +#### Context Example +```json +{ + "Zimperium": { + "PolicyAppSetting": { + "accountId": "2", + "appRiskLookupEnabled": true, + "assigned": true, + "autoActivateKnox": false, + "autoBatteryOptimizationEnabled": true, + "cogitoEnabled": true, + "cogitoThreshold": 70, + "created": "2023-12-05T20:09:16.621+00:00", + "dangerzoneEnabled": true, + "detectionEnabled": true, + "forensicAnalysisEnabled": false, + "global": true, + "groups": [ + { + "accountId": "2", + "created": "2023-12-05T20:09:16.621+00:00", + "description": "Default Group", + "emm": false, + "global": true, + "groupActivations": [], + "id": "37", + "modified": "2023-12-05T20:09:16.621+00:00", + "name": "Default Group", + "staticFilesWritten": "2024-02-06T06:00:37.129+00:00", + "userActivations": [ + { + "id": "40" + } + ], + "zapps": [] + } + ], + "id": "9e", + "jsonHash": "616", + "modified": "2023-12-05T20:09:16.729+00:00", + "name": "Default", + "phishingDBRefreshMinutes": 480, + "phishingEnabled": true, + "phishingLocalClassifierEnabled": true, + "phishingThreshold": 75, + "privacySummaryEnabled": true, + "protoHash": "ea9", + "siteInsightEnabled": false, + "staticFilesWritten": "2023-12-05T20:09:17.418+00:00", + "team": null, + "teamId": null + } + } +} +``` + +#### Human Readable Output + +>### Policy App Settings +>|Id|Name|Detection Enabled|Cogito Enabled|Cogito Threshold|Phishing Enabled|Phishing Threshold|Phishing DB Refresh Minutes|Created|Modified|Static Files Written|Json Hash|Proto Hash|Dangerzone Enabled|Site Insight Enabled|Phishing Local Classifier Enabled|App Risk Lookup Enabled|Auto Battery Optimization Enabled|Auto Activate Knox|Privacy Summary Enabled|Forensic Analysis Enabled|Team|Assigned|Team Id|Global| +>|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +>| 9e | Default | true | true | 70 | true | 75 | 480 | 2023-12-05T20:09:16.621+00:00 | 2023-12-05T20:09:16.729+00:00 | 2023-12-05T20:09:17.418+00:00 | 616 | ea9 | true | false | true | true | true | false | true | false | | true | | true | + + +### zimperium-policy-device-inactivity-list + +*** +Get the policy device inactivity list. + +#### Base Command + +`zimperium-policy-device-inactivity-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| page_size | Maximum number of results to retrieve in each page. If a limit is not provided, default is 50. | Optional | +| page | Page number. Default is 0. | Optional | +| limit | Number of total results to return. Default is 50. | Optional | +| team_id | Used to filter the data by the team the user belongs to. If you provide this the query returns matching entries plus the policies without a team. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.PolicyDeviceInactivity.teamId | String | The team ID for the policy device inactivity list. | +| Zimperium.PolicyDeviceInactivity.id | String | The policy device inactivity list ID. | +| Zimperium.PolicyDeviceInactivity.name | String | The name of the policy device inactivity list. | + +#### Command example +```!zimperium-policy-device-inactivity-list team_id="1"``` +#### Context Example +```json +{ + "Zimperium": { + "PolicyDeviceInactivity": [ + { + "id": "2", + "name": "Default", + "teamId": null + }, + { + "id": "ff3", + "name": "InactivityTest", + "teamId": "1" + } + ] + } +} +``` + +#### Human Readable Output + +>### Device Inactivity List +>|Id|Name|Team Id| +>|---|---|---| +>| 2 | Default | | +>| ff3 | InactivityTest | 1 | + + +### zimperium-policy-device-inactivity-get + +*** +Get policy device inactivity. + +#### Base Command + +`zimperium-policy-device-inactivity-get` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| policy_id | The identifier of the policy. Can be retrieved using zimperium-policy-device-inactivity-list. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| Zimperium.PolicyDeviceInactivity.id | String | The policy device inactivity ID. | +| Zimperium.PolicyDeviceInactivity.accountId | String | The account identifier. | +| Zimperium.PolicyDeviceInactivity.created | Date | The date and time the policy was created. | +| Zimperium.PolicyDeviceInactivity.groups.id | String | The group ID. | +| Zimperium.PolicyDeviceInactivity.groups.name | String | The group name. | +| Zimperium.PolicyDeviceInactivity.inactiveAppSettings.enabled | Boolean | Whether the app settings inactivity is enabled. | +| Zimperium.PolicyDeviceInactivity.inactiveAppSettings.maxWarningsCount | Number | The maximum number of warnings that can be issued for an app. | +| Zimperium.PolicyDeviceInactivity.inactiveAppSettings | Boolean | The inactive app settings. | +| Zimperium.PolicyDeviceInactivity.modified | Date | The policy modified date. | +| Zimperium.PolicyDeviceInactivity.name | String | The name of the policy. | +| Zimperium.PolicyDeviceInactivity.pendingActivationSettings.enabled | Boolean | Whether the device's policy setting is enabled or not. | +| Zimperium.PolicyDeviceInactivity.pendingActivationSettings.maxWarningsCount | Number | The maximum number of warnings that can be issued for the policy. | +| Zimperium.PolicyDeviceInactivity.pendingActivationSettings.sendEmailAndroid | Boolean | Whether to send an email. | +| Zimperium.PolicyDeviceInactivity.pendingActivationSettings.sendEmailIos | Boolean | Whether to send an email. | +| Zimperium.PolicyDeviceInactivity.pendingActivationSettings.timeBeforeWarningDisplayUnits | String | The time before the warning display. | +| Zimperium.PolicyDeviceInactivity.pendingActivationSettings.timeBeforeWarningSeconds | Number | The time before the warning seconds. | +| Zimperium.PolicyDeviceInactivity.pendingActivationSettings.timeBetweenWarningsDisplayUnits | String | The time interval between warning displays. | +| Zimperium.PolicyDeviceInactivity.pendingActivationSettings.timeBetweenWarningsSeconds | Number | The time in seconds between warnings. | +| Zimperium.PolicyDeviceInactivity.teamId | String | The Team ID for the policy device inactivity. | + +#### Command example +```!zimperium-policy-device-inactivity-get policy_id="ff3"``` +#### Context Example +```json +{ + "Zimperium": { + "PolicyDeviceInactivity": { + "accountId": "2", + "created": 1702305515652, + "groups": [ + { + "id": "1", + "name": "GroupTest" + } + ], + "id": "ff3", + "inactiveAppSettings": { + "enabled": false, + "maxWarningsCount": 2, + "notifyDevicesAndroid": false, + "notifyDevicesIos": false, + "sendEmailAndroid": false, + "sendEmailIos": false, + "timeBeforeWarningDisplayUnits": "DAYS", + "timeBeforeWarningSeconds": 259200, + "timeBetweenWarningsDisplayUnits": "DAYS", + "timeBetweenWarningsSeconds": 86400 + }, + "modified": 1702305515652, + "name": "InactivityTest", + "pendingActivationSettings": { + "enabled": false, + "maxWarningsCount": 2, + "sendEmailAndroid": false, + "sendEmailIos": false, + "timeBeforeWarningDisplayUnits": "DAYS", + "timeBeforeWarningSeconds": 259200, + "timeBetweenWarningsDisplayUnits": "DAYS", + "timeBetweenWarningsSeconds": 86400 + }, + "teamId": "1" + } + } +} +``` + +#### Human Readable Output + +>### Device Inactivity +>|Id|Name|Team Id|Pending Activation Settings|Inactive App Settings|Created|Modified| +>|---|---|---|---|---|---|---| +>| ff3 | InactivityTest | 1 | enabled: false
    timeBeforeWarningSeconds: 259200
    timeBeforeWarningDisplayUnits: DAYS
    timeBetweenWarningsSeconds: 86400
    timeBetweenWarningsDisplayUnits: DAYS
    maxWarningsCount: 2
    sendEmailIos: false
    sendEmailAndroid: false | enabled: false
    timeBeforeWarningSeconds: 259200
    timeBeforeWarningDisplayUnits: DAYS
    timeBetweenWarningsSeconds: 86400
    timeBetweenWarningsDisplayUnits: DAYS
    maxWarningsCount: 2
    notifyDevicesIos: false
    notifyDevicesAndroid: false
    sendEmailIos: false
    sendEmailAndroid: false | 2023-12-11 14:38:35 | 2023-12-11 14:38:35 | + + +## Breaking changes from the previous version of this integration +The following sections list the changes in this version. + +### Commands +#### The following commands were removed in this version: +* ***zimperium-events-search*** - this command was replaced by ***zimperium-threat-search***. +* ***zimperium-user-get-by-id*** - this command was replaced by ***zimperium-users-search***. +* ***zimperium-device-get-by-id*** - this command was replaced by ***zimperium-devices-search***. +* ***zimperium-app-classification-get*** - this command was replaced by ***zimperium-app-version-list***. +* ***zimperium-devices-search*** - this command was removed. +* ***file*** - this command was removed. + + +### Arguments +#### The following arguments were removed in this version: + +In the *zimperium-users-search* command: +* *query* +* *email* + +In the *zimperium-devices-search* command: +* *query* + +In the ***zimperium-report-get*** command: +* *bundle_id* +* *itunes_id* +* *app_hash* +* *platform* diff --git a/Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2.py b/Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2.py new file mode 100644 index 000000000000..abda77d72e3a --- /dev/null +++ b/Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2.py @@ -0,0 +1,1105 @@ +import urllib3 +from CommonServerPython import * +import demistomock as demisto + +# Disable insecure warnings +urllib3.disable_warnings() + +DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' +FETCH_FIELD = 'timestamp' + + +class Client(BaseClient): + """ + Client to use in the ZimperiumV2 integration. Overrides BaseClient + """ + + def __init__(self, base_url: str, client_id: str, client_secret: str, verify: bool): + self._headers = {'Content-Type': 'application/json'} + super().__init__(base_url=base_url, verify=verify, headers=self._headers) + access_token = self.auth(client_id, client_secret) + self._headers['Authorization'] = f'Bearer {access_token}' + + def auth(self, client_id: str, client_secret: str): + """ + Args: + client_id: The client id for authentication + client_secret: The client secret for authentication + + Return: + access_token for requests authentication. + """ + body = { + 'clientId': client_id, + 'secret': client_secret, + } + response = self._http_request(method='POST', url_suffix='/auth/v1/api_keys/login', json_data=body) + access_token = response.get('accessToken') + return access_token + + def users_search(self, size: Optional[int], page: Optional[int], team_id: Optional[str] = None, + user_id: Optional[str] = None): + """Search users by sending a GET request. + + Args: + size: response size. + page: response page. + user_id: the id of the user to search. + team_id: the id of the team filter by. + + Returns: + Response from API. + """ + params = assign_params(**{ + 'page': page, + 'size': size, + 'teamId': team_id, + }) + + return self._http_request(method='GET', url_suffix=f'auth/public/v1/users/{user_id if user_id else ""}', + headers=self._headers, + params=params) + + def device_search(self, size: Optional[int], page: Optional[int], device_id: Optional[str]): + """Search devices by sending a GET request. + + Args: + size: response size. + page: response page. + device_id: the device id to get. + + Returns: + Response from API. + """ + params = assign_params(**{ + 'page': page, + 'size': size, + }) + + return self._http_request(method='GET', + url_suffix=f'/devices/public/v2/devices/{device_id if device_id else "start-scroll"}', + headers=self._headers, params=params) + + def report_get(self, app_version_id: Optional[str]): + """ Generates JSON report using GET request. + + Args: + app_version_id: The Id to get the app version JSON report. + + Returns: + Response from API. + """ + + return self._http_request(method='GET', url_suffix=f'/devices/public/v1/appVersions/' + f'{app_version_id}/json', + headers=self._headers) + + def threat_search(self, after: Optional[str], size: Optional[int] = None, + page: Optional[int] = 0, + before: Optional[str] = None, + search_params: Optional[dict] = None, + team_id: Optional[str] = None, + operating_system: Optional[str] = None, + severity: Optional[List] = None, + sort: Optional[str] = None): + """Search threats by sending a GET request. + + Args: + size: response size. + page: response page. + after: threats after this date. + before: threats before this date. + search_params: params to query. + team_id: threats related to team. + operating_system: os of device with a threat. + severity: threat severity. + sort: field to sort by. + Returns: + Response from API. + """ + params = { + 'page': page, + 'size': size, + 'module': 'ZIPS', + 'after': after, + 'before': before, + 'teamId': team_id, + 'os': operating_system, + 'severityName': severity, + 'sort': sort + } + if search_params: + params.update(search_params) + + params = assign_params(**params) + + return self._http_request(method='GET', url_suffix='/threats/public/v1/threats', headers=self._headers, + params=params) + + def app_version_list(self, size: Optional[int], page: Optional[int], bundle_id: Optional[str] = None): + """List App Versions by sending a GET request. + + Args: + bundle_id: The Bundle ID of the app to get its app version. + size: response size. + page: response page. + + Returns: + Response from API. + """ + params = assign_params(**{ + 'query': f'bundleId=={bundle_id}' if bundle_id else None, + 'page': page, + 'size': size, + }) + return self._http_request(method='GET', url_suffix='/devices/public/v1/appVersions', + headers=self._headers, params=params) + + def device_by_cve_get(self, cve_id: Optional[str], size: Optional[int], page: Optional[int], + after: Optional[str] = None, before: Optional[str] = None, + team_id: Optional[str] = None): + """Get Devices that has CVE with cve_id a GET request. + + Args: + cve_id: the ID of the CVE which is input. + size: response size. + page: response page. + after: the date from when the data can be retrieved. + before: the date until when the data can be retrieved. + team_id: filter the data to the respective team. + Returns: + Response from API. + """ + params = assign_params(**{ + 'page': page, + 'size': size, + 'module': 'ZIPS', + 'after': after, + 'before': before, + 'teamId': team_id, + 'cveId': cve_id + }) + + return self._http_request(method='GET', url_suffix='/devices/public/v2/devices/data-cve-filter', headers=self._headers, + params=params) + + def policy_group_list(self, module: Optional[str] = 'ZIPS'): + """List policy groups by sending a GET request. + + Returns: + Response from API. + """ + params = { + 'module': module if module else 'ZIPS', + } + return self._http_request(method='GET', url_suffix='/mtd-policy/public/v1/groups/page', + headers=self._headers, params=params) + + def devices_os_version(self, os_version: Optional[str], size: Optional[int], page: Optional[int], + deleted: Optional[bool] = None, os_patch_date: Optional[str] = None, + after: Optional[str] = None, before: Optional[str] = None, team_id: Optional[str] = None): + """Search devices by os version by sending a GET request. + + Args: + os_version: os version of the device. + deleted: is device deleted. + os_patch_date: os patch date. + size: response size. + page: response page. + after: the date from when the data can be retrieved. + before: the date until when the data can be retrieved. + team_id: filter devices related to the team id. + Returns: + Response from API. + """ + params = assign_params(**{ + 'page': page, + 'size': size, + 'module': 'ZIPS', + 'after': after, + 'before': before, + 'teamId': team_id, + 'osPatchDate': os_patch_date, + 'osVersion': os_version, + 'deleted': deleted, + }) + + return self._http_request(method='GET', url_suffix='/devices/public/v2/devices/data-version-filter', + headers=self._headers, + params=params) + + def cve_devices_get(self, size: Optional[int], page: Optional[int], device_id: Optional[str]): + """Get the CVEs associated with a specific device + + Args: + device_id: the device to query. + size: response size. + page: response page. + Returns: + Response from API. + """ + params = assign_params(**{ + 'page': page, + 'size': size, + 'module': 'ZIPS', + }) + + return self._http_request(method='GET', + url_suffix=f'/devices/public/v2/devices/{device_id}/cves', + headers=self._headers, + params=params) + + def vulnerability_get(self, size: Optional[int], page: Optional[int]): + """Get the list of vulnerabilities. + + Args: + size: response size. + page: response page. + Returns: + Response from API. + """ + params = assign_params(**{ + 'page': page, + 'size': size, + }) + + return self._http_request(method='GET', + url_suffix='/devices/public/v1/os-versions', + headers=self._headers, + params=params) + + def policy_privacy(self, policy_id: Optional[str]): + """Get a privacy policy by id. + + Args: + policy_id: the policy id to query. + + Returns: + Response from API. + """ + return self._http_request(method='GET', + url_suffix=f'/mtd-policy/public/v1/privacy/policies/{policy_id}', + headers=self._headers) + + def policy_threat(self, policy_id: Optional[str]): + """Get a threat policy by id. + + Args: + policy_id: the policy id to query. + + Returns: + Response from API. + """ + + return self._http_request(method='GET', + url_suffix=f'/mtd-policy/public/v1/trm/policies/{policy_id}', + headers=self._headers) + + def policy_phishing(self, policy_id: Optional[str]): + """Get the phishing policy by id. + + Args: + policy_id: the policy id to query. + + Returns: + Response from API. + """ + + return self._http_request(method='GET', + url_suffix=f'/mtd-policy/public/v1/phishing/policies/{policy_id}', + headers=self._headers) + + def policy_app_settings(self, app_settings_policy_id: Optional[str]): + """Get the policy app settings by id. + + Args: + app_settings_policy_id: the policy id to query. + + Returns: + Response from API. + """ + return self._http_request(method='GET', + url_suffix=f'/mtd-policy/public/v1/app-settings/policies/{app_settings_policy_id}', + headers=self._headers) + + def policy_device_inactivity_list(self, size: Optional[int], page: Optional[int], team_id: Optional[str] = None): + """List the device inactivity policies. + + Args: + team_id: filter the data to its respective team. + size: response size. + page: response page. + + Returns: + Response from API. + """ + params = assign_params(**{ + 'teamId': team_id, + 'page': page, + 'size': size, + }) + return self._http_request(method='GET', url_suffix='/devices/public/v1/dormancy/policies', + headers=self._headers, params=params) + + def policy_device_inactivity_get(self, policy_id: Optional[str]): + """Get the device inactivity policy by id. + + Args: + policy_id: the policy id to query. + + Returns: + Response from API. + """ + return self._http_request(method='GET', url_suffix=f'/devices/public/v1/dormancy/policies/{policy_id}', + headers=self._headers) + + +def test_module(client: Client, first_fetch_time: Optional[str], + fetch_query: Optional[list], max_fetch: int, look_back: int = 1) -> str: + """ + Performs basic get request to get incident samples + """ + if demisto.params().get('isFetch'): + fetch_incidents( + client=client, + last_run={}, + fetch_query=fetch_query, + first_fetch_time=first_fetch_time, + max_fetch=max_fetch, + look_back=look_back, + ) + else: + client.users_search(size=10, page=0) + + return 'ok' + + +def users_search_command(client: Client, args: dict) -> CommandResults: + """Search users. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + page = arg_to_number(args.get('page', '0')) + page_size = arg_to_number(args.get('page_size')) + limit = arg_to_number(args.get('limit', '50')) + team_id = args.get('team_id') + user_id = args.get('user_id') + size = page_size if page_size else limit + + response = client.users_search(size=size, page=page, team_id=team_id, user_id=user_id) + + content = response.get('content') if not user_id else response + + hr = tableToMarkdown(name='Users Search Results', t=content, + headers=['id', 'firstName', 'lastName', 'email', 'created', 'role', 'teams'], + headerTransform=pascalToSpace) + + command_results = CommandResults( + outputs_prefix='Zimperium.User', + outputs=content, + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def devices_search_command(client: Client, args: dict) -> CommandResults: + """Search devices. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + page = arg_to_number(args.get('page', '0')) + page_size = arg_to_number(args.get('page_size')) + limit = arg_to_number(args.get('limit', '50')) + device_id = args.get('device_id') + + size = page_size if page_size else limit + + response = client.device_search(size=size, page=page, device_id=device_id) + + content = response.get('content') if not device_id else [response] + hr_output = content.copy() + + for item in hr_output: + bundle_id_item = item.get('zappInstance', [{}])[0].get('bundleId') + item.update({'bundleId': bundle_id_item}) + + hr = tableToMarkdown(name='Device Search Results', t=hr_output, + headers=['riskPostureName', 'id', 'model', 'os', 'bundleId', 'lastSeen'], + removeNull=True, + date_fields=['lastSeen'], + headerTransform=pascalToSpace) + + command_results = CommandResults( + outputs_prefix='Zimperium.Device', + outputs=content, + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def report_get_command(client: Client, args: dict) -> CommandResults: + """Get report by ID. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + app_version_id = args.get('app_version_id') + importance = args.get('importance', 'High') + + response = client.report_get(app_version_id=app_version_id) + + scan_details = response.get('report', {}).get('scanDetails') + if importance != 'All': + # changing the list in place (in the response dict) + scan_details[:] = [entry for entry in scan_details if entry["importance"] == importance] + + hr = tableToMarkdown(name='Report', t=scan_details, + headers=["riskType", "kind", "description", "location", "importance"], + headerTransform=pascalToSpace) + + command_results = CommandResults( + outputs_prefix='Zimperium.Report', + outputs=response, + readable_output=hr, + raw_response=response, + ) + return command_results + + +def threat_search_command(client: Client, args: dict) -> CommandResults: + """Search threats. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + after = arg_to_datetime(args.get('after'), required=True, arg_name='after') + before = arg_to_datetime(args.get('before')) + page = arg_to_number(args.get('page', '0')) + page_size = arg_to_number(args.get('page_size')) + limit = arg_to_number(args.get('limit', '50')) + search_params = argToList(args.get('search_params')) + team_id = args.get('team_id') + operating_system = args.get('os') + severity = args.get('severity') + + after_srt = after.strftime(DATE_FORMAT) if after else None + before_str = before.strftime(DATE_FORMAT) if before else None + + search_params_dict = {key: value for param in search_params for key, value in [param.split('=', 1)]} + size = page_size if page_size else limit + + response = client.threat_search(size=size, page=page, after=after_srt, + before=before_str, search_params=search_params_dict, + team_id=team_id, operating_system=operating_system, severity=severity) + + hr = tableToMarkdown(name='Threat Search Result', t=response.get('content'), + headers=['id', 'severityName', 'state', 'vectorName', + 'threatTypeName', 'os', 'deviceOwner', 'deviceId', + 'teamName', 'timestamp'], + date_fields=['timestamp'], + headerTransform=pascalToSpace) + + command_results = CommandResults( + outputs_prefix='Zimperium.Threat', + outputs=response.get('content'), + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def app_version_list_command(client: Client, args: dict) -> CommandResults: + """List app versions. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + bundle_id = args.get('bundle_id') + page = arg_to_number(args.get('page', '0')) + page_size = arg_to_number(args.get('page_size')) + limit = arg_to_number(args.get('limit', '50')) + + size = page_size if page_size else limit + + response = client.app_version_list(bundle_id=bundle_id, size=size, page=page) + + hr = tableToMarkdown(name='App Version List', t=response.get('content'), + headers=['id', 'name', 'bundleId', 'version', 'platform', + 'security', 'privacy', 'classification', 'developerName', 'created', 'updatedOn'], + date_fields=['created', 'updatedOn'], + headerTransform=pascalToSpace) + + command_results = CommandResults( + outputs_prefix='Zimperium.AppVersion', + outputs=response.get('content'), + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def get_devices_by_cve_command(client: Client, args: dict) -> CommandResults: + """Retrieve the devices associated with a specific CVE + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + cve_id = args.get('cve_id') + after = arg_to_datetime(args.get('after')) + before = arg_to_datetime(args.get('before')) + page = arg_to_number(args.get('page', '0')) + page_size = arg_to_number(args.get('page_size')) + limit = arg_to_number(args.get('limit', '50')) + team_id = args.get('team_id') + + after_srt = after.strftime(DATE_FORMAT) if after else None + before_str = before.strftime(DATE_FORMAT) if before else None + + size = page_size if page_size else limit + + response = client.device_by_cve_get(cve_id=cve_id, size=size, page=page, after=after_srt, + before=before_str, team_id=team_id, ) + + for item in response.get('content', []): + item['cveId'] = cve_id + + hr = tableToMarkdown(name=f'Devices Associated with {cve_id}', t=response.get('content'), + headers=['id', 'zdeviceId', 'teamId', 'os'], + headerTransform=pascalToSpace) + + contex = {'Zimperium.DeviceByCVE(val.id == obj.id && val.cveId == obj.cveId)': response.get('content')} + command_results = CommandResults( + outputs=contex, + readable_output=hr, + raw_response=response, + ) + return command_results + + +def devices_os_version_command(client: Client, args: dict) -> CommandResults: + """Search devices by os version. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + os_version = args.get('os_version') + os_patch_date = arg_to_datetime(args.get('os_patch_date')) + deleted = argToBoolean(args.get('deleted')) if args.get('deleted') else None + after = arg_to_datetime(args.get('after')) + before = arg_to_datetime(args.get('before')) + page = arg_to_number(args.get('page', '0')) + page_size = arg_to_number(args.get('page_size')) + limit = arg_to_number(args.get('limit', '50')) + team_id = args.get('team_id') + + after_srt = after.strftime(DATE_FORMAT) if after else None + os_patch_date_str = os_patch_date.strftime('YYYY-MM-DD') if os_patch_date else None + before_str = before.strftime(DATE_FORMAT) if before else None + + size = page_size if page_size else limit + + response = client.devices_os_version(os_version=os_version, size=size, page=page, after=after_srt, + before=before_str, team_id=team_id, deleted=deleted, os_patch_date=os_patch_date_str) + + hr = tableToMarkdown(name='Device Os Version', t=response.get('content'), + headers=['id', 'teamId', 'os'], + headerTransform=pascalToSpace) + + command_results = CommandResults( + outputs_prefix='Zimperium.DeviceOsVersion', + outputs=response.get('content'), + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def get_cves_by_device_command(client: Client, args: dict) -> CommandResults: + """Search CVE for specific device. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + page = arg_to_number(args.get('page', '0')) + page_size = arg_to_number(args.get('page_size')) + limit = arg_to_number(args.get('limit', '50')) + device_id = args.get('device_id') + size = page_size if page_size else limit + + response = client.cve_devices_get(size=size, page=page, device_id=device_id) + + for item in response.get('content', []): + item['deviceId'] = device_id + + hr = tableToMarkdown(name=f'CVE on Device {device_id}', t=response.get('content'), + headers=['id', 'type', 'severity', 'url', 'activeExploit', 'exploitPocUrl'], + headerTransform=pascalToSpace) + + contex = {'Zimperium.CVEByDevice(val.id == obj.id && val.deviceId == obj.deviceId)': response.get('content')} + command_results = CommandResults( + outputs=contex, + readable_output=hr, + raw_response=response, + ) + return command_results + + +def vulnerability_get_command(client: Client, args: dict) -> CommandResults: + """Gets a list of vulnerabilities. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + page = arg_to_number(args.get('page', '0')) + page_size = arg_to_number(args.get('page_size')) + limit = arg_to_number(args.get('limit', '50')) + size = page_size if page_size else limit + + response = client.vulnerability_get(size=size, page=page) + + hr = tableToMarkdown(name='Vulnerabilities List', t=response.get('content'), + headers=['id', 'os', 'osVersionAndPatchDate', 'osVersion', 'osPatchDate', 'risk', + 'cveCount', 'lastCveSync', 'osRiskChecksum', 'blueBorneVulnerable'], + date_fields=['lastCveSync'], + headerTransform=pascalToSpace) + + command_results = CommandResults( + outputs_prefix='Zimperium.Vulnerability', + outputs=response.get('content'), + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def policy_group_list_command(client: Client, args: dict) -> CommandResults: + """List policies groups. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + module = args.get('module') + response = client.policy_group_list(module) + + hr = tableToMarkdown(name='Policy Group List', t=response.get('content'), + headers=['id', 'name', 'team', 'emmConnectionId', 'privacyId', 'trmId', 'phishingPolicyId', + 'appSettingsId', 'appPolicyId', 'networkPolicyId', 'osRiskPolicyId'], + headerTransform=pascalToSpace, + removeNull=True) + + command_results = CommandResults( + outputs_prefix='Zimperium.PolicyGroup', + outputs=response.get('content'), + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def policy_privacy_get_command(client: Client, args: dict) -> CommandResults: + """Get privacy policy by id. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + policy_id = args.get('policy_id') + + response = client.policy_privacy(policy_id=policy_id) + + hr = tableToMarkdown(name='Privacy Policy', t=response, + headers=['id', 'name', 'created', 'modified', 'team', 'teamId'], + headerTransform=pascalToSpace, + removeNull=True) + + command_results = CommandResults( + outputs_prefix='Zimperium.PolicyPrivacy', + outputs=response, + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def policy_threat_get_command(client: Client, args: dict) -> CommandResults: + """Get threat policy by id. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + policy_id = args.get('policy_id') + + response = client.policy_threat(policy_id=policy_id) + + hr = tableToMarkdown(name='Threat Policy', t=response, + headers=['id', 'isDeployed', 'name', 'created', 'modified'], + headerTransform=pascalToSpace, + removeNull=True) + + command_results = CommandResults( + outputs_prefix='Zimperium.PolicyThreat', + outputs=response, + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def policy_phishing_get_command(client: Client, args: dict) -> CommandResults: + """Get phishing policy by id. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + policy_id = args.get('policy_id') + + response = client.policy_phishing(policy_id=policy_id) + + hr = tableToMarkdown(name='Phishing Policy', t=response, + headers=['id', 'name', 'created', 'modified', 'team', 'teamId', + 'enableSafariBrowserExtensionTutorial', 'enableDnsPhishingTutorial', + 'useLocalVpn', 'useUrlSharing', 'allowEndUserControl', 'useRemoteContentInspection', + 'enableMessageFilterTutorial', + 'phishingDetectionAction', 'phishingPolicyType'], + headerTransform=pascalToSpace, + removeNull=True) + + command_results = CommandResults( + outputs_prefix='Zimperium.PolicyPhishing', + outputs=response, + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def policy_app_settings_get_command(client: Client, args: dict) -> CommandResults: + """Get policy app settings by id. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + + app_settings_policy_id = args.get('app_settings_policy_id') + + response = client.policy_app_settings(app_settings_policy_id=app_settings_policy_id) + + hr = tableToMarkdown(name='Policy App Settings', t=response, + headers=['id', 'name', 'detectionEnabled', 'cogitoEnabled', 'cogitoThreshold', 'phishingEnabled', + 'phishingThreshold', 'phishingDBRefreshMinutes', 'created', 'modified', 'staticFilesWritten', + 'jsonHash', 'protoHash', 'dangerzoneEnabled', 'siteInsightEnabled', + 'phishingLocalClassifierEnabled', 'appRiskLookupEnabled', 'autoBatteryOptimizationEnabled', + 'autoActivateKnox', 'privacySummaryEnabled', 'forensicAnalysisEnabled', 'team', 'assigned', + 'teamId', 'global'], + headerTransform=pascalToSpace) + + command_results = CommandResults( + outputs_prefix='Zimperium.PolicyAppSetting', + outputs=response, + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def policy_device_inactivity_list_command(client: Client, args: dict) -> CommandResults: + """List device inactivity policies + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + page = arg_to_number(args.get('page', '0')) + page_size = arg_to_number(args.get('page_size')) + limit = arg_to_number(args.get('limit', '50')) + team_id = args.get('team_id') + + size = page_size if page_size else limit + + response = client.policy_device_inactivity_list(size=size, page=page, team_id=team_id) + + hr = tableToMarkdown(name='Device Inactivity List', t=response, + headers=['id', 'name', 'teamId'], + headerTransform=pascalToSpace) + + command_results = CommandResults( + outputs_prefix='Zimperium.PolicyDeviceInactivity', + outputs=response, + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def policy_device_inactivity_get_command(client: Client, args: dict) -> CommandResults: + """Get device inactivity policy by id. + + Args: + client: Client object with request. + args: Usually demisto.args() + + Returns: + Outputs. + """ + policy_id = args.get('policy_id') + + response = client.policy_device_inactivity_get(policy_id=policy_id) + + hr = tableToMarkdown(name='Device Inactivity', t=response, + headers=['id', 'name', 'teamId', 'pendingActivationSettings', + 'inactiveAppSettings', 'created', 'modified', + ], + headerTransform=pascalToSpace, + removeNull=True, + date_fields=['created', 'modified'] + ) + + command_results = CommandResults( + outputs_prefix='Zimperium.PolicyDeviceInactivity', + outputs=response, + outputs_key_field='id', + readable_output=hr, + raw_response=response, + ) + return command_results + + +def fetch_incidents(client: Client, last_run: dict, fetch_query: Optional[list], + first_fetch_time: Optional[str], max_fetch: int, look_back: int = 1) -> tuple[list, dict]: + """ + This function will execute each interval (default is 1 minute). + + Args: + client (Client): Zimperium V2 client. + last_run (dict): the last fetch object. + fetch_query(list): fetch query to search. + first_fetch_time (time): If last_run is None then fetch all incidents since first_fetch_time. + max_fetch(int): max events to fetch. + look_back(int): minutes to look back when fetching. + + Returns: + next_run: This will be last_run in the next fetch-incidents + incidents: Incidents that will be created + """ + fetch_query = fetch_query or [] + demisto.debug(f"Last run before the fetch run: {last_run}") + limit = last_run.get('limit', max_fetch) + start_time, end_time = get_fetch_run_time_range( + last_run=last_run, + first_fetch=first_fetch_time, + look_back=look_back, + date_format=DATE_FORMAT, + ) + demisto.debug(f"fetching incidents between {start_time=} and {end_time=}, with {limit=}") + + search_params = {key: value for param in fetch_query for key, value in [param.split('=', 1)]} + demisto.debug(f'The query for fetch: {search_params}') + + res = client.threat_search(after=start_time, search_params=search_params, size=limit, sort=FETCH_FIELD) + incidents_res = res.get('content', []) + demisto.debug(f'Got {len(incidents_res)} incidents from the API, before filtering') + + incidents_filtered = filter_incidents_by_duplicates_and_limit( + incidents_res=incidents_res, + last_run=last_run, + fetch_limit=max_fetch, + id_field='id' + ) + demisto.debug(f'After filtering, there are {len(incidents_filtered)} incidents') + + incidents: list[dict] = [] + for incident in incidents_filtered: + occurred = timestamp_to_datestring(incident.get(FETCH_FIELD)) + demisto.debug(f'Looking on: {incident.get("id")}, {occurred=}') + incident[FETCH_FIELD] = occurred + incidents.append({ + 'name': f"Threat {incident.get('id')} on Device ID {incident.get('deviceId')}", + 'occurred': occurred, + 'dbotMirrorId': incident.get('id'), + 'severity': incident.get('severity'), + 'rawJSON': json.dumps(incident) + }) + + last_run = update_last_run_object( + last_run=last_run, + incidents=incidents_filtered, + fetch_limit=max_fetch, + start_fetch_time=start_time, + end_fetch_time=end_time, + look_back=look_back, + created_time_field=FETCH_FIELD, + id_field='id', + date_format=DATE_FORMAT, + increase_last_run_time=False + ) + demisto.debug(f"Last run after the fetch run: {last_run}") + return incidents, last_run + + +def main(): # pragma: no cover + params = demisto.params() + client_id = params.get('credentials', {}).get('identifier') + client_secret = params.get('credentials', {}).get('password') + base_url = urljoin(params.get('url'), '/api') + verify = not params.get('insecure', False) + + # fetch params + max_fetch = arg_to_number(params.get('max_fetch', 50)) or 50 + fetch_query = argToList(params.get('fetch_query')) or [] + first_fetch = params.get('first_fetch', '7 days').strip() + look_back = arg_to_number(params.get('look_back')) or 1 + + first_fetch_time = arg_to_datetime(first_fetch) + first_fetch_time_str = first_fetch_time.strftime(DATE_FORMAT) if first_fetch_time else None + + command = demisto.command() + args = demisto.args() + demisto.debug(f'Command being called is {demisto.command()}') + try: + client = Client(base_url=base_url, client_id=client_id, client_secret=client_secret, verify=verify) + if command == 'test-module': + # This is the call made when pressing the integration Test button. + return_results(test_module(client, first_fetch_time_str, fetch_query, max_fetch, look_back)) + + elif command == 'fetch-incidents': + incidents, next_run = fetch_incidents( + client=client, + last_run=demisto.getLastRun(), + fetch_query=fetch_query, + first_fetch_time=first_fetch_time_str, + max_fetch=max_fetch, + look_back=look_back, + ) + demisto.setLastRun(next_run) + demisto.incidents(incidents) + + elif command == 'zimperium-users-search': + return_results(users_search_command(client, args)) + + elif command == 'zimperium-devices-search': + return_results(devices_search_command(client, args)) + + elif command == 'zimperium-report-get': + return_results(report_get_command(client, args)) + + elif command == 'zimperium-threat-search': + return_results(threat_search_command(client, args)) + + elif command == 'zimperium-app-version-list': + return_results(app_version_list_command(client, args)) + + elif command == 'zimperium-get-devices-by-cve': + return_results(get_devices_by_cve_command(client, args)) + + elif command == 'zimperium-devices-os-version': + return_results(devices_os_version_command(client, args)) + + elif command == 'zimperium-get-cves-by-device': + return_results(get_cves_by_device_command(client, args)) + + elif command == 'zimperium-vulnerability-get': + return_results(vulnerability_get_command(client, args)) + + elif command == 'zimperium-policy-group-list': + return_results(policy_group_list_command(client, args)) + + elif command == 'zimperium-policy-privacy-get': + return_results(policy_privacy_get_command(client, args)) + + elif command == 'zimperium-policy-threat-get': + return_results(policy_threat_get_command(client, args)) + + elif command == 'zimperium-policy-phishing-get': + return_results(policy_phishing_get_command(client, args)) + + elif command == 'zimperium-policy-app-settings-get': + return_results(policy_app_settings_get_command(client, args)) + + elif command == 'zimperium-policy-device-inactivity-list': + return_results(policy_device_inactivity_list_command(client, args)) + + elif command == 'zimperium-policy-device-inactivity-get': + return_results(policy_device_inactivity_get_command(client, args)) + else: + raise NotImplementedError(f'Command "{command}" is not implemented.') + + except Exception as err: + return_error(str(err), err) + + +if __name__ in ('__main__', '__builtin__', 'builtins'): + main() diff --git a/Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2.yml b/Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2.yml new file mode 100644 index 000000000000..6269d07d7c55 --- /dev/null +++ b/Packs/Zimperium/Integrations/ZimperiumV2/ZimperiumV2.yml @@ -0,0 +1,1353 @@ +category: Network Security +commonfields: + id: Zimperium v2 + version: -1 +configuration: +- defaultvalue: https://mtduat.zimperium.com + display: Server URL (e.g., https://mtduat.zimperium.com) + name: url + required: true + type: 0 + section: Connect +- display: Client ID + name: credentials + type: 9 + required: true + displaypassword: Client Secret + section: Connect +- display: Fetch incidents + name: isFetch + type: 8 + required: false +- display: Search Params (e.g, severityName=CRITICAL,teamId=myId) + additionalinfo: Comma-separated list of search parameters and its values. Same as for the "zimperium-threat-search" command. + name: fetch_query + type: 0 + required: false + section: Collect +- defaultvalue: '50' + display: Max fetch + name: max_fetch + type: 0 + required: false + section: Collect +- defaultvalue: 7 days + display: First fetch timestamp (

    z&!YOfOM{cb=?>i02AMPY+Y2QTv|#U|{Pfv}e9=N9zm&4l9A1$Qj_U#x*8<-*3|J{z zEL|gnWaLYpLo0mgCK>WB@v`&gSi_6Dd{D;|QvOy^Cr?R0#VkKFL?*nIzCA!<{|k|- zV6sfM3f)wiBGf+2_?pGmcia*qZP-_3bi+!8ZV7$R8x)hTR^5tjs_IGu4aX@}Nh)X{EaXCGL8oAdIy%K*V l@ERT^VEI4b92{`W-?lwnA#>Sx Date: Sun, 18 Feb 2024 15:11:51 +0200 Subject: [PATCH 005/272] Upgrade `python3` docker images 0-20 coverage rate (#32446) * update docker * updateRN * revert RN * update RN * Bump pack from version Base to 1.33.31. * update RN after merge master * Bump pack from version ArcherRSA to 1.2.16. --------- Co-authored-by: Content Bot --- Packs/ArcherRSA/ReleaseNotes/1_2_16.md | 6 ++ .../ArcherCreateIncidentExample.yml | 2 +- Packs/ArcherRSA/pack_metadata.json | 2 +- .../Attlasian_IAM/Attlasian_IAM.yml | 2 +- Packs/Attlasian/ReleaseNotes/1_1_15.md | 6 ++ Packs/Attlasian/pack_metadata.json | 2 +- Packs/Base/ReleaseNotes/1_33_31.md | 9 +++ .../DBotShowClusteringModelInfo.yml | 2 +- .../DeleteIndicatorRelationships.yml | 2 +- Packs/Base/pack_metadata.json | 2 +- Packs/BigFix/Integrations/BigFix/BigFix.yml | 2 +- Packs/BigFix/ReleaseNotes/1_0_15.md | 6 ++ Packs/BigFix/pack_metadata.json | 4 +- .../BluecatAddressManager.yml | 2 +- .../ReleaseNotes/1_1_13.md | 6 ++ .../BluecatAddressManager/pack_metadata.json | 2 +- Packs/C2sec/Integrations/C2sec/C2sec.yml | 2 +- Packs/C2sec/ReleaseNotes/1_0_11.md | 6 ++ Packs/C2sec/pack_metadata.json | 2 +- Packs/CIRCL/Integrations/CIRCL/CIRCL.yml | 2 +- Packs/CIRCL/ReleaseNotes/1_0_22.md | 6 ++ Packs/CIRCL/pack_metadata.json | 2 +- Packs/Campaign/ReleaseNotes/3_4_4.md | 12 +++ .../ShowCampaignUniqueRecipients.yml | 2 +- .../ShowCampaignUniqueSenders.yml | 2 +- .../ShowNumberOfCampaignIncidents.yml | 2 +- Packs/Campaign/pack_metadata.json | 2 +- .../ReleaseNotes/2_1_45.md | 9 +++ .../Scripts/CBFindIP/CBFindIP.yml | 2 +- .../CBLiveGetFile_V2/CBLiveGetFile_V2.yml | 2 +- .../pack_metadata.json | 2 +- Packs/Change_Management/ReleaseNotes/1_0_4.md | 6 ++ .../Scripts/IncidentState/IncidentState.yml | 2 +- Packs/Change_Management/pack_metadata.json | 2 +- Packs/Cherwell/ReleaseNotes/1_0_19.md | 21 +++++ .../CherwellCreateIncident.yml | 2 +- .../CherwellGetIncident.yml | 2 +- .../CherwellIncidentOwnTask.yml | 2 +- .../CherwellIncidentUnlinkTask.yml | 2 +- .../CherwellQueryIncidents.yml | 2 +- .../CherwellUpdateIncident.yml | 2 +- Packs/Cherwell/pack_metadata.json | 2 +- .../ReleaseNotes/1_0_15.md | 9 +++ .../XCloudProviderWidget.yml | 2 +- .../displayCloudIndicators.yml | 2 +- .../CloudIncidentResponse/pack_metadata.json | 2 +- Packs/CommonScripts/ReleaseNotes/1_13_40.md | 78 +++++++++++++++++++ .../AddDBotScoreToContext.yml | 2 +- .../AssignToMeButton/AssignToMeButton.yml | 2 +- .../Scripts/CVSSCalculator/CVSSCalculator.yml | 2 +- .../CalculateTimeDifference.yml | 2 +- .../CloseInvestigationAsDuplicate.yml | 2 +- .../CompareIncidentsLabels.yml | 2 +- .../ContextContains/ContextContains.yml | 2 +- .../ConvertDateToUTC/ConvertDateToUTC.yml | 2 +- .../CopyContextToField/CopyContextToField.yml | 2 +- .../Scripts/DemistoVersion/DemistoVersion.yml | 2 +- .../Scripts/EncodeToAscii/EncodeToAscii.yml | 2 +- .../ExportContextToJSONFile.yml | 2 +- .../GenerateRandomString.yml | 2 +- .../GenerateSummaryReportButton.yml | 2 +- .../Scripts/IPToHost/IPToHost.yml | 2 +- .../IndicatorMaliciousRatioCalculation.yml | 2 +- .../IsDomainInternal/IsDomainInternal.yml | 2 +- .../Scripts/IsIPPrivate/IsIPPrivate.yml | 2 +- .../LinkIncidentsButton.yml | 2 +- .../LinkIncidentsWithRetry.yml | 2 +- .../LoadJSONFileToContext.yml | 2 +- .../MarkAsEvidenceByTag.yml | 2 +- .../PopulateCriticalAssets.yml | 2 +- .../Scripts/SetDateField/SetDateField.yml | 2 +- .../displayUtilitiesResults.yml | 2 +- Packs/CommonScripts/pack_metadata.json | 2 +- .../ContentManagement/ReleaseNotes/1_2_18.md | 6 ++ .../Scripts/GetPrBranches/GetPrBranches.yml | 2 +- Packs/ContentManagement/pack_metadata.json | 2 +- .../Integrations/CounterTack/CounterTack.yml | 2 +- Packs/CounterTack/ReleaseNotes/1_0_9.md | 6 ++ Packs/CounterTack/pack_metadata.json | 2 +- .../CrowdStrikeOpenAPI/CrowdStrikeOpenAPI.yml | 2 +- .../CrowdStrikeOpenAPI/ReleaseNotes/1_0_18.md | 6 ++ Packs/CrowdStrikeOpenAPI/pack_metadata.json | 2 +- Packs/CuckooSandbox/ReleaseNotes/1_1_5.md | 6 ++ .../CuckooDisplayReport.yml | 2 +- Packs/CuckooSandbox/pack_metadata.json | 2 +- .../DBotTruthBombs/DBotTruthBombs.yml | 2 +- Packs/DBotTruthBombs/ReleaseNotes/1_0_8.md | 12 +++ .../Scripts/FactsAboutYou/FactsAboutYou.yml | 2 +- Packs/DBotTruthBombs/pack_metadata.json | 2 +- .../Integrations/EasyVista/EasyVista.yml | 2 +- Packs/EasyVista/ReleaseNotes/1_0_9.md | 6 ++ Packs/EasyVista/pack_metadata.json | 2 +- .../FeedAlienVaultReputation.yml | 2 +- Packs/FeedAlienVault/ReleaseNotes/1_1_30.md | 6 ++ Packs/FeedAlienVault/pack_metadata.json | 2 +- .../MajesticMillion/MajesticMillion.yml | 2 +- .../ReleaseNotes/1_1_14.md | 6 ++ Packs/FeedMajesticMillion/pack_metadata.json | 2 +- .../FeedTorExitAddresses.yml | 2 +- .../ReleaseNotes/1_0_9.md | 6 ++ Packs/FeedTorExitAddresses/pack_metadata.json | 2 +- .../Feedsslabusech/Feedsslabusech.yml | 2 +- Packs/Feedsslabusech/ReleaseNotes/1_1_26.md | 6 ++ Packs/Feedsslabusech/pack_metadata.json | 2 +- .../FidelisEndpoint/FidelisEndpoint.yml | 2 +- Packs/FidelisEndpoint/ReleaseNotes/1_0_6.md | 6 ++ Packs/FidelisEndpoint/pack_metadata.json | 2 +- .../ReleaseNotes/1_2_61.md | 12 +++ .../FiltersAndTransformers/Scripts/DT/DT.yml | 2 +- .../GetValuesOfMultipleFIelds.yml | 2 +- .../Scripts/StripChar/StripChar.yml | 2 +- .../FiltersAndTransformers/pack_metadata.json | 2 +- .../Integrations/Forescout/Forescout.yml | 2 +- Packs/Forescout/ReleaseNotes/1_0_9.md | 6 ++ Packs/Forescout/pack_metadata.json | 2 +- .../Integrations/ImpervaWAF/ImpervaWAF.yml | 2 +- Packs/Imperva_WAF/ReleaseNotes/1_0_18.md | 6 ++ Packs/Imperva_WAF/pack_metadata.json | 2 +- .../Integrations/IvantiHeat/IvantiHeat.yml | 2 +- Packs/IvantiHeat/ReleaseNotes/1_0_10.md | 18 +++++ .../IvantiHeatCloseIncidentExample.yml | 2 +- .../IvantiHeatCreateIncidentExample.yml | 2 +- .../IvantiHeatCreateProblemExample.yml | 2 +- Packs/IvantiHeat/pack_metadata.json | 2 +- .../LogRhythmRest/LogRhythmRest.yml | 2 +- Packs/LogRhythmRest/ReleaseNotes/2_0_22.md | 6 ++ Packs/LogRhythmRest/pack_metadata.json | 2 +- Packs/ML/ReleaseNotes/1_4_10.md | 6 ++ .../ExtendQueryBasedOnPhishingLabels.yml | 2 +- Packs/ML/pack_metadata.json | 2 +- .../ReleaseNotes/1_6_37.md | 27 +++++++ ...reachResponseCompletedTasksCountWidget.yml | 2 +- ...achResponseEradicationTasksCountWidget.yml | 2 +- ...dBreachResponseHuntingTasksCountWidget.yml | 2 +- ...eachResponseMitigationTasksCountWidget.yml | 2 +- ...reachResponseRemainingTasksCountWidget.yml | 2 +- ...achResponseRemediationTasksCountWidget.yml | 2 +- ...reachResponseTotalIndicatorCountWidget.yml | 2 +- ...pidBreachResponseTotalTasksCountWidget.yml | 2 +- .../pack_metadata.json | 2 +- .../ReleaseNotes/4_5_17.md | 9 +++ .../MS365DefenderCountIncidentCategories.yml | 2 +- .../MS365DefenderUserListToTable.yml | 2 +- Packs/Microsoft365Defender/pack_metadata.json | 2 +- .../PrismaAccessEgressIPFeed.yml | 2 +- Packs/PrismaAccess/ReleaseNotes/2_1_4.md | 6 ++ Packs/PrismaAccess/pack_metadata.json | 2 +- Packs/ProofpointTAP/ReleaseNotes/1_2_11.md | 9 +++ .../ProofpointTAPMostAttackedUsers.yml | 2 +- .../ProofpointTapTopClickers.yml | 2 +- Packs/ProofpointTAP/pack_metadata.json | 2 +- Packs/Salesforce/ReleaseNotes/2_0_23.md | 9 +++ .../GenerateProfileId/GenerateProfileId.yml | 2 +- .../GenerateTimeZone/GenerateTimeZone.yml | 2 +- Packs/Salesforce/pack_metadata.json | 2 +- Packs/ServiceNow/ReleaseNotes/2_5_53.md | 6 ++ .../ServiceNowIncidentStatus.yml | 2 +- Packs/ServiceNow/pack_metadata.json | 2 +- .../Integrations/Slack_IAM/Slack_IAM.yml | 2 +- Packs/Slack/ReleaseNotes/3_4_5.md | 6 ++ Packs/Slack/pack_metadata.json | 2 +- .../Integrations/Telegram/Telegram.yml | 2 +- Packs/Telegram/ReleaseNotes/1_0_8.md | 6 ++ Packs/Telegram/pack_metadata.json | 2 +- .../ThreatIntelReports/ReleaseNotes/1_0_13.md | 9 +++ .../PublishThreatIntelReport.yml | 2 +- .../UnpublishThreatIntelReport.yml | 2 +- Packs/ThreatIntelReports/pack_metadata.json | 2 +- .../Integrations/ThreatMiner/ThreatMiner.yml | 2 +- Packs/ThreatMiner/ReleaseNotes/1_0_13.md | 6 ++ Packs/ThreatMiner/pack_metadata.json | 2 +- Packs/Troubleshoot/ReleaseNotes/2_0_18.md | 15 ++++ .../TroubleshootAggregateResults.yml | 2 +- .../TroubleshootExecuteCommand.yml | 2 +- .../TroubleshootGetCommandandArgs.yml | 2 +- .../TroubleshootInstanceField.yml | 2 +- Packs/Troubleshoot/pack_metadata.json | 2 +- .../WhatIsMyBrowser/WhatIsMyBrowser.yml | 2 +- Packs/WhatIsMyBrowser/ReleaseNotes/1_0_11.md | 6 ++ Packs/WhatIsMyBrowser/pack_metadata.json | 2 +- 180 files changed, 559 insertions(+), 139 deletions(-) create mode 100644 Packs/ArcherRSA/ReleaseNotes/1_2_16.md create mode 100644 Packs/Attlasian/ReleaseNotes/1_1_15.md create mode 100644 Packs/Base/ReleaseNotes/1_33_31.md create mode 100644 Packs/BigFix/ReleaseNotes/1_0_15.md create mode 100644 Packs/BluecatAddressManager/ReleaseNotes/1_1_13.md create mode 100644 Packs/C2sec/ReleaseNotes/1_0_11.md create mode 100644 Packs/CIRCL/ReleaseNotes/1_0_22.md create mode 100644 Packs/Campaign/ReleaseNotes/3_4_4.md create mode 100644 Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/2_1_45.md create mode 100644 Packs/Change_Management/ReleaseNotes/1_0_4.md create mode 100644 Packs/Cherwell/ReleaseNotes/1_0_19.md create mode 100644 Packs/CloudIncidentResponse/ReleaseNotes/1_0_15.md create mode 100644 Packs/CommonScripts/ReleaseNotes/1_13_40.md create mode 100644 Packs/ContentManagement/ReleaseNotes/1_2_18.md create mode 100644 Packs/CounterTack/ReleaseNotes/1_0_9.md create mode 100644 Packs/CrowdStrikeOpenAPI/ReleaseNotes/1_0_18.md create mode 100644 Packs/CuckooSandbox/ReleaseNotes/1_1_5.md create mode 100644 Packs/DBotTruthBombs/ReleaseNotes/1_0_8.md create mode 100644 Packs/EasyVista/ReleaseNotes/1_0_9.md create mode 100644 Packs/FeedAlienVault/ReleaseNotes/1_1_30.md create mode 100644 Packs/FeedMajesticMillion/ReleaseNotes/1_1_14.md create mode 100644 Packs/FeedTorExitAddresses/ReleaseNotes/1_0_9.md create mode 100644 Packs/Feedsslabusech/ReleaseNotes/1_1_26.md create mode 100644 Packs/FidelisEndpoint/ReleaseNotes/1_0_6.md create mode 100644 Packs/FiltersAndTransformers/ReleaseNotes/1_2_61.md create mode 100644 Packs/Forescout/ReleaseNotes/1_0_9.md create mode 100644 Packs/Imperva_WAF/ReleaseNotes/1_0_18.md create mode 100644 Packs/IvantiHeat/ReleaseNotes/1_0_10.md create mode 100644 Packs/LogRhythmRest/ReleaseNotes/2_0_22.md create mode 100644 Packs/ML/ReleaseNotes/1_4_10.md create mode 100644 Packs/MajorBreachesInvestigationandResponse/ReleaseNotes/1_6_37.md create mode 100644 Packs/Microsoft365Defender/ReleaseNotes/4_5_17.md create mode 100644 Packs/PrismaAccess/ReleaseNotes/2_1_4.md create mode 100644 Packs/ProofpointTAP/ReleaseNotes/1_2_11.md create mode 100644 Packs/Salesforce/ReleaseNotes/2_0_23.md create mode 100644 Packs/ServiceNow/ReleaseNotes/2_5_53.md create mode 100644 Packs/Slack/ReleaseNotes/3_4_5.md create mode 100644 Packs/Telegram/ReleaseNotes/1_0_8.md create mode 100644 Packs/ThreatIntelReports/ReleaseNotes/1_0_13.md create mode 100644 Packs/ThreatMiner/ReleaseNotes/1_0_13.md create mode 100644 Packs/Troubleshoot/ReleaseNotes/2_0_18.md create mode 100644 Packs/WhatIsMyBrowser/ReleaseNotes/1_0_11.md diff --git a/Packs/ArcherRSA/ReleaseNotes/1_2_16.md b/Packs/ArcherRSA/ReleaseNotes/1_2_16.md new file mode 100644 index 000000000000..8a5060008b0d --- /dev/null +++ b/Packs/ArcherRSA/ReleaseNotes/1_2_16.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### ArcherCreateIncidentExample + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/ArcherRSA/Scripts/ArcherCreateIncidentExample/ArcherCreateIncidentExample.yml b/Packs/ArcherRSA/Scripts/ArcherCreateIncidentExample/ArcherCreateIncidentExample.yml index d8908f23e4cd..116a97870887 100644 --- a/Packs/ArcherRSA/Scripts/ArcherCreateIncidentExample/ArcherCreateIncidentExample.yml +++ b/Packs/ArcherRSA/Scripts/ArcherCreateIncidentExample/ArcherCreateIncidentExample.yml @@ -33,7 +33,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 skipprepare: diff --git a/Packs/ArcherRSA/pack_metadata.json b/Packs/ArcherRSA/pack_metadata.json index d60048714851..d98608e5ff24 100644 --- a/Packs/ArcherRSA/pack_metadata.json +++ b/Packs/ArcherRSA/pack_metadata.json @@ -2,7 +2,7 @@ "name": "RSA Archer", "description": "The RSA Archer GRC Platform provides a common foundation for managing policies, controls, risks, assessments and deficiencies across lines of business.", "support": "xsoar", - "currentVersion": "1.2.15", + "currentVersion": "1.2.16", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Attlasian/Integrations/Attlasian_IAM/Attlasian_IAM.yml b/Packs/Attlasian/Integrations/Attlasian_IAM/Attlasian_IAM.yml index 259c1984516a..f2ab47579153 100644 --- a/Packs/Attlasian/Integrations/Attlasian_IAM/Attlasian_IAM.yml +++ b/Packs/Attlasian/Integrations/Attlasian_IAM/Attlasian_IAM.yml @@ -238,7 +238,7 @@ script: type: String - description: Retrieves a User Profile schema, which holds all of the user fields within the application. Used for outgoing-mapping through the Get Schema option. name: get-mapping-fields - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 ismappable: true isremotesyncout: true script: '-' diff --git a/Packs/Attlasian/ReleaseNotes/1_1_15.md b/Packs/Attlasian/ReleaseNotes/1_1_15.md new file mode 100644 index 000000000000..c83a3cb90369 --- /dev/null +++ b/Packs/Attlasian/ReleaseNotes/1_1_15.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Atlassian IAM + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Attlasian/pack_metadata.json b/Packs/Attlasian/pack_metadata.json index e1abca28981d..5a3a2d901a08 100644 --- a/Packs/Attlasian/pack_metadata.json +++ b/Packs/Attlasian/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Atlassian IAM", "description": "Atlassian IAM Integration allows the customers to do the generic ILM management operations such as create, update, delete, etc.", "support": "xsoar", - "currentVersion": "1.1.14", + "currentVersion": "1.1.15", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Base/ReleaseNotes/1_33_31.md b/Packs/Base/ReleaseNotes/1_33_31.md new file mode 100644 index 000000000000..b7a6e3971e62 --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_33_31.md @@ -0,0 +1,9 @@ + +#### Scripts + +##### DeleteIndicatorRelationships + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### DBotShowClusteringModelInfo + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Base/Scripts/DBotShowClusteringModelInfo/DBotShowClusteringModelInfo.yml b/Packs/Base/Scripts/DBotShowClusteringModelInfo/DBotShowClusteringModelInfo.yml index 190b39bd285b..89e4ee18a040 100644 --- a/Packs/Base/Scripts/DBotShowClusteringModelInfo/DBotShowClusteringModelInfo.yml +++ b/Packs/Base/Scripts/DBotShowClusteringModelInfo/DBotShowClusteringModelInfo.yml @@ -29,6 +29,6 @@ type: python fromversion: 6.2.0 tests: - No tests (auto formatted) -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 marketplaces: - xsoar diff --git a/Packs/Base/Scripts/DeleteIndicatorRelationships/DeleteIndicatorRelationships.yml b/Packs/Base/Scripts/DeleteIndicatorRelationships/DeleteIndicatorRelationships.yml index e7b94c5032cd..390d70004561 100644 --- a/Packs/Base/Scripts/DeleteIndicatorRelationships/DeleteIndicatorRelationships.yml +++ b/Packs/Base/Scripts/DeleteIndicatorRelationships/DeleteIndicatorRelationships.yml @@ -15,7 +15,7 @@ tags: timeout: '0' type: python subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 fromversion: 6.2.0 tests: - Relationships scripts - Test diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index 875097b5a2e5..c303b18714ef 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.33.30", + "currentVersion": "1.33.31", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", diff --git a/Packs/BigFix/Integrations/BigFix/BigFix.yml b/Packs/BigFix/Integrations/BigFix/BigFix.yml index db8f0e25d94f..85c30cbe6c98 100644 --- a/Packs/BigFix/Integrations/BigFix/BigFix.yml +++ b/Packs/BigFix/Integrations/BigFix/BigFix.yml @@ -478,5 +478,5 @@ script: script: '-' subtype: python3 type: python - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 fromversion: 5.0.0 diff --git a/Packs/BigFix/ReleaseNotes/1_0_15.md b/Packs/BigFix/ReleaseNotes/1_0_15.md new file mode 100644 index 000000000000..2e4f58b4f67e --- /dev/null +++ b/Packs/BigFix/ReleaseNotes/1_0_15.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### BigFix + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/BigFix/pack_metadata.json b/Packs/BigFix/pack_metadata.json index 82adee64fa3b..894d103827f6 100644 --- a/Packs/BigFix/pack_metadata.json +++ b/Packs/BigFix/pack_metadata.json @@ -2,7 +2,7 @@ "name": "HCL BigFix", "description": "HCL BigFix Patch provides an automated, simplified patching process that is administered from a single console.", "support": "xsoar", - "currentVersion": "1.0.14", + "currentVersion": "1.0.15", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", @@ -17,4 +17,4 @@ "xsoar", "marketplacev2" ] -} +} \ No newline at end of file diff --git a/Packs/BluecatAddressManager/Integrations/BluecatAddressManager/BluecatAddressManager.yml b/Packs/BluecatAddressManager/Integrations/BluecatAddressManager/BluecatAddressManager.yml index 4b8aa6b092e7..60ca23d554eb 100644 --- a/Packs/BluecatAddressManager/Integrations/BluecatAddressManager/BluecatAddressManager.yml +++ b/Packs/BluecatAddressManager/Integrations/BluecatAddressManager/BluecatAddressManager.yml @@ -162,7 +162,7 @@ script: - contextPath: BlueCat.AddressManager.Range.Parents.CIDR description: Classless Inter-Domain Routing. type: String - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 runonce: false script: '-' subtype: python3 diff --git a/Packs/BluecatAddressManager/ReleaseNotes/1_1_13.md b/Packs/BluecatAddressManager/ReleaseNotes/1_1_13.md new file mode 100644 index 000000000000..ff9e050e0f23 --- /dev/null +++ b/Packs/BluecatAddressManager/ReleaseNotes/1_1_13.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Bluecat Address Manager + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/BluecatAddressManager/pack_metadata.json b/Packs/BluecatAddressManager/pack_metadata.json index fc2e8db67b8d..41fbbce4aab6 100644 --- a/Packs/BluecatAddressManager/pack_metadata.json +++ b/Packs/BluecatAddressManager/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Bluecat Address Manager", "description": "Use the BlueCat Address Manager integration to enrich IP addresses and manage response policies.", "support": "xsoar", - "currentVersion": "1.1.12", + "currentVersion": "1.1.13", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/C2sec/Integrations/C2sec/C2sec.yml b/Packs/C2sec/Integrations/C2sec/C2sec.yml index 3f71242db8b9..fa6c5eee2f75 100644 --- a/Packs/C2sec/Integrations/C2sec/C2sec.yml +++ b/Packs/C2sec/Integrations/C2sec/C2sec.yml @@ -199,6 +199,6 @@ script: type: string description: Query Data for specific component for companies in the portfolio runonce: false - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 tests: - No tests (auto formatted) diff --git a/Packs/C2sec/ReleaseNotes/1_0_11.md b/Packs/C2sec/ReleaseNotes/1_0_11.md new file mode 100644 index 000000000000..95d42ee2d45f --- /dev/null +++ b/Packs/C2sec/ReleaseNotes/1_0_11.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### C2sec irisk + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/C2sec/pack_metadata.json b/Packs/C2sec/pack_metadata.json index d760b1599f8a..4696f06328fa 100644 --- a/Packs/C2sec/pack_metadata.json +++ b/Packs/C2sec/pack_metadata.json @@ -2,7 +2,7 @@ "name": "C2sec irisk", "description": "Understand Your Cyber Exposure as Easy as a Google Search", "support": "xsoar", - "currentVersion": "1.0.10", + "currentVersion": "1.0.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CIRCL/Integrations/CIRCL/CIRCL.yml b/Packs/CIRCL/Integrations/CIRCL/CIRCL.yml index 649fdbd4b2eb..ebd81ed8fcbe 100644 --- a/Packs/CIRCL/Integrations/CIRCL/CIRCL.yml +++ b/Packs/CIRCL/Integrations/CIRCL/CIRCL.yml @@ -116,7 +116,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 tests: - CirclIntegrationTest fromversion: 5.0.0 diff --git a/Packs/CIRCL/ReleaseNotes/1_0_22.md b/Packs/CIRCL/ReleaseNotes/1_0_22.md new file mode 100644 index 000000000000..932797c6547d --- /dev/null +++ b/Packs/CIRCL/ReleaseNotes/1_0_22.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### CIRCL + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/CIRCL/pack_metadata.json b/Packs/CIRCL/pack_metadata.json index 412ffa58cf16..836c143c69f5 100644 --- a/Packs/CIRCL/pack_metadata.json +++ b/Packs/CIRCL/pack_metadata.json @@ -2,7 +2,7 @@ "name": "CIRCL", "description": "The Computer Incident Response Center Luxembourg (CIRCL) is a government-driven initiative designed to provide a systematic response facility to computer security threats and incidents.\nThis pack includes:\n# CIRCL Passive DNS which is a database storing historical DNS records from various resources.\n# CIRCL Passive SSL is a database storing historical X.509 certificates seen per IP address. The Passive SSL historical data is indexed per IP address.\n# CIRCL CVE Search, interface to search publicly known information from security vulnerabilities in software and hardware along with their corresponding exposures.", "support": "xsoar", - "currentVersion": "1.0.21", + "currentVersion": "1.0.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Campaign/ReleaseNotes/3_4_4.md b/Packs/Campaign/ReleaseNotes/3_4_4.md new file mode 100644 index 000000000000..f659d3befc99 --- /dev/null +++ b/Packs/Campaign/ReleaseNotes/3_4_4.md @@ -0,0 +1,12 @@ + +#### Scripts + +##### ShowCampaignUniqueSenders + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### ShowNumberOfCampaignIncidents + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### ShowCampaignUniqueRecipients + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Campaign/Scripts/ShowCampaignUniqueRecipients/ShowCampaignUniqueRecipients.yml b/Packs/Campaign/Scripts/ShowCampaignUniqueRecipients/ShowCampaignUniqueRecipients.yml index 6dd22be988fc..652e08b0c8ed 100644 --- a/Packs/Campaign/Scripts/ShowCampaignUniqueRecipients/ShowCampaignUniqueRecipients.yml +++ b/Packs/Campaign/Scripts/ShowCampaignUniqueRecipients/ShowCampaignUniqueRecipients.yml @@ -10,7 +10,7 @@ comment: Displays the number of unique recipients of an email campaign. enabled: true scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.0.0 tests: diff --git a/Packs/Campaign/Scripts/ShowCampaignUniqueSenders/ShowCampaignUniqueSenders.yml b/Packs/Campaign/Scripts/ShowCampaignUniqueSenders/ShowCampaignUniqueSenders.yml index f6f9864df48d..a447c60d67a7 100644 --- a/Packs/Campaign/Scripts/ShowCampaignUniqueSenders/ShowCampaignUniqueSenders.yml +++ b/Packs/Campaign/Scripts/ShowCampaignUniqueSenders/ShowCampaignUniqueSenders.yml @@ -11,7 +11,7 @@ enabled: true scripttarget: 0 subtype: python3 fromversion: 6.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole tests: - No tests (auto formatted) diff --git a/Packs/Campaign/Scripts/ShowNumberOfCampaignIncidents/ShowNumberOfCampaignIncidents.yml b/Packs/Campaign/Scripts/ShowNumberOfCampaignIncidents/ShowNumberOfCampaignIncidents.yml index 8dcd99f4ebf6..312af40b7e04 100644 --- a/Packs/Campaign/Scripts/ShowNumberOfCampaignIncidents/ShowNumberOfCampaignIncidents.yml +++ b/Packs/Campaign/Scripts/ShowNumberOfCampaignIncidents/ShowNumberOfCampaignIncidents.yml @@ -11,7 +11,7 @@ enabled: true scripttarget: 0 subtype: python3 fromversion: 6.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole tests: - No tests (auto formatted) diff --git a/Packs/Campaign/pack_metadata.json b/Packs/Campaign/pack_metadata.json index d04df1d315de..f77a831765ac 100644 --- a/Packs/Campaign/pack_metadata.json +++ b/Packs/Campaign/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Phishing Campaign", "description": "This pack can help you find related phishing, spam or other types of email incidents and characterize campaigns.", "support": "xsoar", - "currentVersion": "3.4.3", + "currentVersion": "3.4.4", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/2_1_45.md b/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/2_1_45.md new file mode 100644 index 000000000000..a55197e6ddbe --- /dev/null +++ b/Packs/Carbon_Black_Enterprise_Response/ReleaseNotes/2_1_45.md @@ -0,0 +1,9 @@ + +#### Scripts + +##### CBFindIP + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CBLiveGetFile_V2 + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Carbon_Black_Enterprise_Response/Scripts/CBFindIP/CBFindIP.yml b/Packs/Carbon_Black_Enterprise_Response/Scripts/CBFindIP/CBFindIP.yml index b138cca3409c..23af799d071a 100644 --- a/Packs/Carbon_Black_Enterprise_Response/Scripts/CBFindIP/CBFindIP.yml +++ b/Packs/Carbon_Black_Enterprise_Response/Scripts/CBFindIP/CBFindIP.yml @@ -48,4 +48,4 @@ tests: dependson: must: [] fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 diff --git a/Packs/Carbon_Black_Enterprise_Response/Scripts/CBLiveGetFile_V2/CBLiveGetFile_V2.yml b/Packs/Carbon_Black_Enterprise_Response/Scripts/CBLiveGetFile_V2/CBLiveGetFile_V2.yml index b2c78806a1f5..ee4e8b7308bb 100644 --- a/Packs/Carbon_Black_Enterprise_Response/Scripts/CBLiveGetFile_V2/CBLiveGetFile_V2.yml +++ b/Packs/Carbon_Black_Enterprise_Response/Scripts/CBLiveGetFile_V2/CBLiveGetFile_V2.yml @@ -105,7 +105,7 @@ tags: - endpoint timeout: '0' type: python -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - No Test dependson: diff --git a/Packs/Carbon_Black_Enterprise_Response/pack_metadata.json b/Packs/Carbon_Black_Enterprise_Response/pack_metadata.json index b19a774dec75..cb1d28a6e48a 100644 --- a/Packs/Carbon_Black_Enterprise_Response/pack_metadata.json +++ b/Packs/Carbon_Black_Enterprise_Response/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Carbon Black Enterprise Response", "description": "Query and respond with Carbon Black endpoint detection and response.", "support": "xsoar", - "currentVersion": "2.1.44", + "currentVersion": "2.1.45", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Change_Management/ReleaseNotes/1_0_4.md b/Packs/Change_Management/ReleaseNotes/1_0_4.md new file mode 100644 index 000000000000..635d62ec67dd --- /dev/null +++ b/Packs/Change_Management/ReleaseNotes/1_0_4.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### IncidentState + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Change_Management/Scripts/IncidentState/IncidentState.yml b/Packs/Change_Management/Scripts/IncidentState/IncidentState.yml index eec247ad1f25..2df66816c8e6 100644 --- a/Packs/Change_Management/Scripts/IncidentState/IncidentState.yml +++ b/Packs/Change_Management/Scripts/IncidentState/IncidentState.yml @@ -6,7 +6,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: "" -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: IncidentState runas: DBotWeakRole diff --git a/Packs/Change_Management/pack_metadata.json b/Packs/Change_Management/pack_metadata.json index 8f4faa5fa1c0..5c6c4d3a6bae 100644 --- a/Packs/Change_Management/pack_metadata.json +++ b/Packs/Change_Management/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Change Management", "description": "If you use Pan-Os or Panorama as your enterprise firewall and Jira or ServiceNow as your enterprise ticketing system, this pack will assist you to perform a well coordinated and documented process.", "support": "xsoar", - "currentVersion": "1.0.3", + "currentVersion": "1.0.4", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Cherwell/ReleaseNotes/1_0_19.md b/Packs/Cherwell/ReleaseNotes/1_0_19.md new file mode 100644 index 000000000000..1c90d783db39 --- /dev/null +++ b/Packs/Cherwell/ReleaseNotes/1_0_19.md @@ -0,0 +1,21 @@ + +#### Scripts + +##### CherwellIncidentUnlinkTask + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CherwellIncidentOwnTask + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CherwellGetIncident + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CherwellCreateIncident + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CherwellQueryIncidents + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CherwellUpdateIncident + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Cherwell/Scripts/CherwellCreateIncident/CherwellCreateIncident.yml b/Packs/Cherwell/Scripts/CherwellCreateIncident/CherwellCreateIncident.yml index ece46308df41..916fd07fdf9b 100644 --- a/Packs/Cherwell/Scripts/CherwellCreateIncident/CherwellCreateIncident.yml +++ b/Packs/Cherwell/Scripts/CherwellCreateIncident/CherwellCreateIncident.yml @@ -39,7 +39,7 @@ type: python dependson: must: - Cherwell|||cherwell-create-business-object -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 subtype: python3 tests: - Cherwell Example Scripts - test diff --git a/Packs/Cherwell/Scripts/CherwellGetIncident/CherwellGetIncident.yml b/Packs/Cherwell/Scripts/CherwellGetIncident/CherwellGetIncident.yml index dec5b58eae46..b0620a66019c 100644 --- a/Packs/Cherwell/Scripts/CherwellGetIncident/CherwellGetIncident.yml +++ b/Packs/Cherwell/Scripts/CherwellGetIncident/CherwellGetIncident.yml @@ -49,7 +49,7 @@ tags: [Cherwell] dependson: must: - Cherwell|||cherwell-get-business-object -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 subtype: python3 tests: - Cherwell Example Scripts - test diff --git a/Packs/Cherwell/Scripts/CherwellIncidentOwnTask/CherwellIncidentOwnTask.yml b/Packs/Cherwell/Scripts/CherwellIncidentOwnTask/CherwellIncidentOwnTask.yml index 5e66777d23f9..1a3823fb7c3b 100644 --- a/Packs/Cherwell/Scripts/CherwellIncidentOwnTask/CherwellIncidentOwnTask.yml +++ b/Packs/Cherwell/Scripts/CherwellIncidentOwnTask/CherwellIncidentOwnTask.yml @@ -10,7 +10,7 @@ commonfields: id: CherwellIncidentOwnTask version: -1 name: CherwellIncidentOwnTask -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 subtype: python3 script: '-' timeout: '0' diff --git a/Packs/Cherwell/Scripts/CherwellIncidentUnlinkTask/CherwellIncidentUnlinkTask.yml b/Packs/Cherwell/Scripts/CherwellIncidentUnlinkTask/CherwellIncidentUnlinkTask.yml index 661191dc7dde..38d01554af2e 100644 --- a/Packs/Cherwell/Scripts/CherwellIncidentUnlinkTask/CherwellIncidentUnlinkTask.yml +++ b/Packs/Cherwell/Scripts/CherwellIncidentUnlinkTask/CherwellIncidentUnlinkTask.yml @@ -13,7 +13,7 @@ name: CherwellIncidentUnlinkTask script: '-' timeout: '0' type: python -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 subtype: python3 tags: [Cherwell] dependson: diff --git a/Packs/Cherwell/Scripts/CherwellQueryIncidents/CherwellQueryIncidents.yml b/Packs/Cherwell/Scripts/CherwellQueryIncidents/CherwellQueryIncidents.yml index 8809f0fa2605..da8b76a71abd 100644 --- a/Packs/Cherwell/Scripts/CherwellQueryIncidents/CherwellQueryIncidents.yml +++ b/Packs/Cherwell/Scripts/CherwellQueryIncidents/CherwellQueryIncidents.yml @@ -42,7 +42,7 @@ outputs: script: '-' timeout: '0' type: python -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 subtype: python3 tests: - Cherwell Example Scripts - test diff --git a/Packs/Cherwell/Scripts/CherwellUpdateIncident/CherwellUpdateIncident.yml b/Packs/Cherwell/Scripts/CherwellUpdateIncident/CherwellUpdateIncident.yml index 3ac9cadf5021..aca4fa261e2d 100644 --- a/Packs/Cherwell/Scripts/CherwellUpdateIncident/CherwellUpdateIncident.yml +++ b/Packs/Cherwell/Scripts/CherwellUpdateIncident/CherwellUpdateIncident.yml @@ -44,7 +44,7 @@ outputs: script: '-' timeout: '0' type: python -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 subtype: python3 tests: - Cherwell Example Scripts - test diff --git a/Packs/Cherwell/pack_metadata.json b/Packs/Cherwell/pack_metadata.json index f6828b4688a6..e8f3c92977b8 100644 --- a/Packs/Cherwell/pack_metadata.json +++ b/Packs/Cherwell/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cherwell", "description": "Cloud-based IT service management solution", "support": "xsoar", - "currentVersion": "1.0.18", + "currentVersion": "1.0.19", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CloudIncidentResponse/ReleaseNotes/1_0_15.md b/Packs/CloudIncidentResponse/ReleaseNotes/1_0_15.md new file mode 100644 index 000000000000..08c50952ab59 --- /dev/null +++ b/Packs/CloudIncidentResponse/ReleaseNotes/1_0_15.md @@ -0,0 +1,9 @@ + +#### Scripts + +##### XCloudProviderWidget + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### displayCloudIndicators + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/CloudIncidentResponse/Scripts/XCloudProviderWidget/XCloudProviderWidget.yml b/Packs/CloudIncidentResponse/Scripts/XCloudProviderWidget/XCloudProviderWidget.yml index a107ede8c6ce..7c690d8a7bdd 100644 --- a/Packs/CloudIncidentResponse/Scripts/XCloudProviderWidget/XCloudProviderWidget.yml +++ b/Packs/CloudIncidentResponse/Scripts/XCloudProviderWidget/XCloudProviderWidget.yml @@ -10,7 +10,7 @@ comment: 'This script returns an HTML result of the cloud providers in the incid enabled: true scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.8.0 tests: diff --git a/Packs/CloudIncidentResponse/Scripts/displayCloudIndicators/displayCloudIndicators.yml b/Packs/CloudIncidentResponse/Scripts/displayCloudIndicators/displayCloudIndicators.yml index 4f8cd5ac2e01..2e513f4e2344 100644 --- a/Packs/CloudIncidentResponse/Scripts/displayCloudIndicators/displayCloudIndicators.yml +++ b/Packs/CloudIncidentResponse/Scripts/displayCloudIndicators/displayCloudIndicators.yml @@ -10,7 +10,7 @@ comment: Display the Cloud indicators found in a dynamic-section enabled: true scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.8.0 tests: diff --git a/Packs/CloudIncidentResponse/pack_metadata.json b/Packs/CloudIncidentResponse/pack_metadata.json index 84dba991c9ee..98460efae1a2 100644 --- a/Packs/CloudIncidentResponse/pack_metadata.json +++ b/Packs/CloudIncidentResponse/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cloud Incident Response", "description": "This content Pack helps you automate collection, investigation, and remediation of incidents related to cloud infrastructure activities in AWS, Azure, and GCP.", "support": "xsoar", - "currentVersion": "1.0.14", + "currentVersion": "1.0.15", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CommonScripts/ReleaseNotes/1_13_40.md b/Packs/CommonScripts/ReleaseNotes/1_13_40.md new file mode 100644 index 000000000000..e7e8b03cfe32 --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_13_40.md @@ -0,0 +1,78 @@ + +#### Scripts + +##### LinkIncidentsWithRetry + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CVSSCalculator + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### ExportContextToJSONFile + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### displayUtilitiesResults + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### PopulateCriticalAssets + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### LinkIncidentsButton + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### ConvertDatetoUTC + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### AssignToMeButton + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### IsDomainInternal + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### IndicatorMaliciousRatioCalculation + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### IPToHost + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### MarkAsEvidenceByTag + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CopyContextToField + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### AddDBotScoreToContext + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CloseInvestigationAsDuplicate + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### SetDateField + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CompareIncidentsLabels + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### ContextContains + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### GenerateSummaryReportButton + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### DemistoVersion + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### IsIPPrivate + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### GenerateRandomString + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### EncodeToAscii + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### LoadJSONFileToContext + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### CalculateTimeDifference + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/CommonScripts/Scripts/AddDBotScoreToContext/AddDBotScoreToContext.yml b/Packs/CommonScripts/Scripts/AddDBotScoreToContext/AddDBotScoreToContext.yml index 4c20b2817b37..302f52cc9583 100644 --- a/Packs/CommonScripts/Scripts/AddDBotScoreToContext/AddDBotScoreToContext.yml +++ b/Packs/CommonScripts/Scripts/AddDBotScoreToContext/AddDBotScoreToContext.yml @@ -26,7 +26,7 @@ comment: Add DBot score to context for indicators with custom vendor, score, rel commonfields: id: AddDBotScoreToContext version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: AddDBotScoreToContext runas: DBotWeakRole diff --git a/Packs/CommonScripts/Scripts/AssignToMeButton/AssignToMeButton.yml b/Packs/CommonScripts/Scripts/AssignToMeButton/AssignToMeButton.yml index c22cb91edddd..1dcc7026d632 100644 --- a/Packs/CommonScripts/Scripts/AssignToMeButton/AssignToMeButton.yml +++ b/Packs/CommonScripts/Scripts/AssignToMeButton/AssignToMeButton.yml @@ -2,7 +2,7 @@ comment: 'Assigns the current Incident to the Cortex XSOAR user who clicked the commonfields: id: AssignToMeButton version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: AssignToMeButton runas: DBotWeakRole diff --git a/Packs/CommonScripts/Scripts/CVSSCalculator/CVSSCalculator.yml b/Packs/CommonScripts/Scripts/CVSSCalculator/CVSSCalculator.yml index 404f7b353059..eaa0f8fcda78 100644 --- a/Packs/CommonScripts/Scripts/CVSSCalculator/CVSSCalculator.yml +++ b/Packs/CommonScripts/Scripts/CVSSCalculator/CVSSCalculator.yml @@ -240,5 +240,5 @@ outputs: description: Version of CVSS used in the calculation. type: number subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 fromversion: 5.0.0 diff --git a/Packs/CommonScripts/Scripts/CalculateTimeDifference/CalculateTimeDifference.yml b/Packs/CommonScripts/Scripts/CalculateTimeDifference/CalculateTimeDifference.yml index 5ebc69947fda..60ba2e3c4487 100644 --- a/Packs/CommonScripts/Scripts/CalculateTimeDifference/CalculateTimeDifference.yml +++ b/Packs/CommonScripts/Scripts/CalculateTimeDifference/CalculateTimeDifference.yml @@ -28,4 +28,4 @@ runas: DBotWeakRole tests: - Impossible Traveler - Test fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 diff --git a/Packs/CommonScripts/Scripts/CloseInvestigationAsDuplicate/CloseInvestigationAsDuplicate.yml b/Packs/CommonScripts/Scripts/CloseInvestigationAsDuplicate/CloseInvestigationAsDuplicate.yml index 56955bd0c093..d7f69cc2abc4 100644 --- a/Packs/CommonScripts/Scripts/CloseInvestigationAsDuplicate/CloseInvestigationAsDuplicate.yml +++ b/Packs/CommonScripts/Scripts/CloseInvestigationAsDuplicate/CloseInvestigationAsDuplicate.yml @@ -15,6 +15,6 @@ args: description: Duplicate incident id scripttarget: 0 fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - No tests (auto formatted) diff --git a/Packs/CommonScripts/Scripts/CompareIncidentsLabels/CompareIncidentsLabels.yml b/Packs/CommonScripts/Scripts/CompareIncidentsLabels/CompareIncidentsLabels.yml index 618df6055f96..f4115a842ef6 100644 --- a/Packs/CommonScripts/Scripts/CompareIncidentsLabels/CompareIncidentsLabels.yml +++ b/Packs/CommonScripts/Scripts/CompareIncidentsLabels/CompareIncidentsLabels.yml @@ -23,6 +23,6 @@ timeout: '0' type: python subtype: python3 fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - CompareIncidentsLabels-test-playbook diff --git a/Packs/CommonScripts/Scripts/ContextContains/ContextContains.yml b/Packs/CommonScripts/Scripts/ContextContains/ContextContains.yml index 452fa71184d2..03d722c57b30 100644 --- a/Packs/CommonScripts/Scripts/ContextContains/ContextContains.yml +++ b/Packs/CommonScripts/Scripts/ContextContains/ContextContains.yml @@ -17,6 +17,6 @@ args: description: Value to search scripttarget: 0 fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - No tests (auto formatted) diff --git a/Packs/CommonScripts/Scripts/ConvertDateToUTC/ConvertDateToUTC.yml b/Packs/CommonScripts/Scripts/ConvertDateToUTC/ConvertDateToUTC.yml index 3daa070b3f41..d2b792355662 100644 --- a/Packs/CommonScripts/Scripts/ConvertDateToUTC/ConvertDateToUTC.yml +++ b/Packs/CommonScripts/Scripts/ConvertDateToUTC/ConvertDateToUTC.yml @@ -28,7 +28,7 @@ outputs: type: Unknown scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 tests: diff --git a/Packs/CommonScripts/Scripts/CopyContextToField/CopyContextToField.yml b/Packs/CommonScripts/Scripts/CopyContextToField/CopyContextToField.yml index ec9d6f17b085..1777780cda3f 100644 --- a/Packs/CommonScripts/Scripts/CopyContextToField/CopyContextToField.yml +++ b/Packs/CommonScripts/Scripts/CopyContextToField/CopyContextToField.yml @@ -32,6 +32,6 @@ timeout: '0' type: python subtype: python3 fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - CopyContextToFieldTest diff --git a/Packs/CommonScripts/Scripts/DemistoVersion/DemistoVersion.yml b/Packs/CommonScripts/Scripts/DemistoVersion/DemistoVersion.yml index 3eaa43086f7a..d4ef4905475f 100644 --- a/Packs/CommonScripts/Scripts/DemistoVersion/DemistoVersion.yml +++ b/Packs/CommonScripts/Scripts/DemistoVersion/DemistoVersion.yml @@ -16,7 +16,7 @@ outputs: type: string scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 marketplaces: diff --git a/Packs/CommonScripts/Scripts/EncodeToAscii/EncodeToAscii.yml b/Packs/CommonScripts/Scripts/EncodeToAscii/EncodeToAscii.yml index 21c387674fd1..a199048a3558 100644 --- a/Packs/CommonScripts/Scripts/EncodeToAscii/EncodeToAscii.yml +++ b/Packs/CommonScripts/Scripts/EncodeToAscii/EncodeToAscii.yml @@ -18,6 +18,6 @@ outputs: type: string scripttarget: 0 fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - No tests (auto formatted) diff --git a/Packs/CommonScripts/Scripts/ExportContextToJSONFile/ExportContextToJSONFile.yml b/Packs/CommonScripts/Scripts/ExportContextToJSONFile/ExportContextToJSONFile.yml index 21d5cbb1257d..b0ad63b4922e 100644 --- a/Packs/CommonScripts/Scripts/ExportContextToJSONFile/ExportContextToJSONFile.yml +++ b/Packs/CommonScripts/Scripts/ExportContextToJSONFile/ExportContextToJSONFile.yml @@ -9,7 +9,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: "" -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: ExportContextToJSONFile runas: DBotWeakRole diff --git a/Packs/CommonScripts/Scripts/GenerateRandomString/GenerateRandomString.yml b/Packs/CommonScripts/Scripts/GenerateRandomString/GenerateRandomString.yml index 080930a8f49e..d69a332f03a5 100644 --- a/Packs/CommonScripts/Scripts/GenerateRandomString/GenerateRandomString.yml +++ b/Packs/CommonScripts/Scripts/GenerateRandomString/GenerateRandomString.yml @@ -49,4 +49,4 @@ scripttarget: 0 tests: - RandomStringGenerateTest fromversion: 6.2.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 diff --git a/Packs/CommonScripts/Scripts/GenerateSummaryReportButton/GenerateSummaryReportButton.yml b/Packs/CommonScripts/Scripts/GenerateSummaryReportButton/GenerateSummaryReportButton.yml index 770c564852f5..f1dd182289a5 100644 --- a/Packs/CommonScripts/Scripts/GenerateSummaryReportButton/GenerateSummaryReportButton.yml +++ b/Packs/CommonScripts/Scripts/GenerateSummaryReportButton/GenerateSummaryReportButton.yml @@ -2,7 +2,7 @@ comment: This button will generate summary 'Case Report' template for a given In commonfields: id: GenerateSummaryReportButton version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: GenerateSummaryReportButton runas: DBotWeakRole diff --git a/Packs/CommonScripts/Scripts/IPToHost/IPToHost.yml b/Packs/CommonScripts/Scripts/IPToHost/IPToHost.yml index efeb51647d73..ea005c717028 100644 --- a/Packs/CommonScripts/Scripts/IPToHost/IPToHost.yml +++ b/Packs/CommonScripts/Scripts/IPToHost/IPToHost.yml @@ -24,6 +24,6 @@ outputs: type: string scripttarget: 0 fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - IPToHost - Test diff --git a/Packs/CommonScripts/Scripts/IndicatorMaliciousRatioCalculation/IndicatorMaliciousRatioCalculation.yml b/Packs/CommonScripts/Scripts/IndicatorMaliciousRatioCalculation/IndicatorMaliciousRatioCalculation.yml index 3ac1449baed7..d9d8fba6562b 100644 --- a/Packs/CommonScripts/Scripts/IndicatorMaliciousRatioCalculation/IndicatorMaliciousRatioCalculation.yml +++ b/Packs/CommonScripts/Scripts/IndicatorMaliciousRatioCalculation/IndicatorMaliciousRatioCalculation.yml @@ -44,4 +44,4 @@ timeout: 300ns fromversion: 5.0.0 tests: - IndicatorMaliciousRatioCalculation_test -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 diff --git a/Packs/CommonScripts/Scripts/IsDomainInternal/IsDomainInternal.yml b/Packs/CommonScripts/Scripts/IsDomainInternal/IsDomainInternal.yml index ceba2474b991..8554b2b00b2b 100644 --- a/Packs/CommonScripts/Scripts/IsDomainInternal/IsDomainInternal.yml +++ b/Packs/CommonScripts/Scripts/IsDomainInternal/IsDomainInternal.yml @@ -28,7 +28,7 @@ outputs: type: boolean scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.5.0 marketplaces: diff --git a/Packs/CommonScripts/Scripts/IsIPPrivate/IsIPPrivate.yml b/Packs/CommonScripts/Scripts/IsIPPrivate/IsIPPrivate.yml index a701eab16e9c..290998bb8e47 100644 --- a/Packs/CommonScripts/Scripts/IsIPPrivate/IsIPPrivate.yml +++ b/Packs/CommonScripts/Scripts/IsIPPrivate/IsIPPrivate.yml @@ -32,7 +32,7 @@ outputs: description: Any tags that were added to the indicator. The tags are added by this script if they were specified for the IP or IP range in the Cortex XSOAR list. scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.5.0 marketplaces: diff --git a/Packs/CommonScripts/Scripts/LinkIncidentsButton/LinkIncidentsButton.yml b/Packs/CommonScripts/Scripts/LinkIncidentsButton/LinkIncidentsButton.yml index 958ac323d95a..1b2d980c89c9 100644 --- a/Packs/CommonScripts/Scripts/LinkIncidentsButton/LinkIncidentsButton.yml +++ b/Packs/CommonScripts/Scripts/LinkIncidentsButton/LinkIncidentsButton.yml @@ -14,7 +14,7 @@ comment: | commonfields: id: LinkIncidentsButton version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: LinkIncidentsButton runas: DBotWeakRole diff --git a/Packs/CommonScripts/Scripts/LinkIncidentsWithRetry/LinkIncidentsWithRetry.yml b/Packs/CommonScripts/Scripts/LinkIncidentsWithRetry/LinkIncidentsWithRetry.yml index 39678c11236f..a843ae9e8b7a 100644 --- a/Packs/CommonScripts/Scripts/LinkIncidentsWithRetry/LinkIncidentsWithRetry.yml +++ b/Packs/CommonScripts/Scripts/LinkIncidentsWithRetry/LinkIncidentsWithRetry.yml @@ -18,7 +18,7 @@ scripttarget: 0 comment: |- Use this script to avoid DB version errors when simultaneously running multiple linked incidents. fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - No tests (auto formatted) marketplaces: diff --git a/Packs/CommonScripts/Scripts/LoadJSONFileToContext/LoadJSONFileToContext.yml b/Packs/CommonScripts/Scripts/LoadJSONFileToContext/LoadJSONFileToContext.yml index 1027daa2de0c..1a678553ea86 100644 --- a/Packs/CommonScripts/Scripts/LoadJSONFileToContext/LoadJSONFileToContext.yml +++ b/Packs/CommonScripts/Scripts/LoadJSONFileToContext/LoadJSONFileToContext.yml @@ -12,7 +12,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: "" -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: LoadJSONFileToContext runas: DBotWeakRole diff --git a/Packs/CommonScripts/Scripts/MarkAsEvidenceByTag/MarkAsEvidenceByTag.yml b/Packs/CommonScripts/Scripts/MarkAsEvidenceByTag/MarkAsEvidenceByTag.yml index d236cf303063..1903af81892e 100644 --- a/Packs/CommonScripts/Scripts/MarkAsEvidenceByTag/MarkAsEvidenceByTag.yml +++ b/Packs/CommonScripts/Scripts/MarkAsEvidenceByTag/MarkAsEvidenceByTag.yml @@ -23,6 +23,6 @@ tags: - Utility type: python fromversion: 6.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - No tests (auto formatted) diff --git a/Packs/CommonScripts/Scripts/PopulateCriticalAssets/PopulateCriticalAssets.yml b/Packs/CommonScripts/Scripts/PopulateCriticalAssets/PopulateCriticalAssets.yml index 346a356798cb..04a38e185ba2 100644 --- a/Packs/CommonScripts/Scripts/PopulateCriticalAssets/PopulateCriticalAssets.yml +++ b/Packs/CommonScripts/Scripts/PopulateCriticalAssets/PopulateCriticalAssets.yml @@ -18,4 +18,4 @@ runas: DBotWeakRole tests: - Calculate Severity - Generic v2 - Test fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 diff --git a/Packs/CommonScripts/Scripts/SetDateField/SetDateField.yml b/Packs/CommonScripts/Scripts/SetDateField/SetDateField.yml index 9b7f34ace338..a14cdff04683 100644 --- a/Packs/CommonScripts/Scripts/SetDateField/SetDateField.yml +++ b/Packs/CommonScripts/Scripts/SetDateField/SetDateField.yml @@ -15,6 +15,6 @@ args: description: "The name of the incident custom field of type date" scripttarget: 0 fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - No tests (auto formatted) diff --git a/Packs/CommonScripts/Scripts/displayUtilitiesResults/displayUtilitiesResults.yml b/Packs/CommonScripts/Scripts/displayUtilitiesResults/displayUtilitiesResults.yml index 6c164a280547..e43c7863e7df 100644 --- a/Packs/CommonScripts/Scripts/displayUtilitiesResults/displayUtilitiesResults.yml +++ b/Packs/CommonScripts/Scripts/displayUtilitiesResults/displayUtilitiesResults.yml @@ -10,7 +10,7 @@ tags: enabled: true scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.10.0 tests: diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index c5f5b73d6cc4..ef668157d2b1 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.13.39", + "currentVersion": "1.13.40", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/ContentManagement/ReleaseNotes/1_2_18.md b/Packs/ContentManagement/ReleaseNotes/1_2_18.md new file mode 100644 index 000000000000..0406cdc76929 --- /dev/null +++ b/Packs/ContentManagement/ReleaseNotes/1_2_18.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### GetPrBranches + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/ContentManagement/Scripts/GetPrBranches/GetPrBranches.yml b/Packs/ContentManagement/Scripts/GetPrBranches/GetPrBranches.yml index 52e9bc47b058..41eee1484574 100644 --- a/Packs/ContentManagement/Scripts/GetPrBranches/GetPrBranches.yml +++ b/Packs/ContentManagement/Scripts/GetPrBranches/GetPrBranches.yml @@ -5,7 +5,7 @@ commonfields: contentitemexportablefields: contentitemfields: fromServerVersion: '' -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: GetPrBranches runas: DBotWeakRole diff --git a/Packs/ContentManagement/pack_metadata.json b/Packs/ContentManagement/pack_metadata.json index 9a7199f3ca40..0f41abe9da0a 100644 --- a/Packs/ContentManagement/pack_metadata.json +++ b/Packs/ContentManagement/pack_metadata.json @@ -2,7 +2,7 @@ "name": "XSOAR CI/CD", "description": "This pack enables you to orchestrate your XSOAR system configuration.", "support": "xsoar", - "currentVersion": "1.2.17", + "currentVersion": "1.2.18", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CounterTack/Integrations/CounterTack/CounterTack.yml b/Packs/CounterTack/Integrations/CounterTack/CounterTack.yml index 41c497d843a2..4d93f3613e6d 100644 --- a/Packs/CounterTack/Integrations/CounterTack/CounterTack.yml +++ b/Packs/CounterTack/Integrations/CounterTack/CounterTack.yml @@ -1145,7 +1145,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 tests: - no tests fromversion: 5.0.0 diff --git a/Packs/CounterTack/ReleaseNotes/1_0_9.md b/Packs/CounterTack/ReleaseNotes/1_0_9.md new file mode 100644 index 000000000000..18619bce4e1c --- /dev/null +++ b/Packs/CounterTack/ReleaseNotes/1_0_9.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### CounterTack + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/CounterTack/pack_metadata.json b/Packs/CounterTack/pack_metadata.json index 902b7561c756..d5e62aa6af2a 100644 --- a/Packs/CounterTack/pack_metadata.json +++ b/Packs/CounterTack/pack_metadata.json @@ -2,7 +2,7 @@ "name": "CounterTack", "description": "CounterTack empowers endpoint security teams to assure endpoint protection for Identifying Cyber Threats. Integrating a predictive endpoint protection platform", "support": "xsoar", - "currentVersion": "1.0.8", + "currentVersion": "1.0.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CrowdStrikeOpenAPI/Integrations/CrowdStrikeOpenAPI/CrowdStrikeOpenAPI.yml b/Packs/CrowdStrikeOpenAPI/Integrations/CrowdStrikeOpenAPI/CrowdStrikeOpenAPI.yml index c46c7d06e578..e341e0de6910 100644 --- a/Packs/CrowdStrikeOpenAPI/Integrations/CrowdStrikeOpenAPI/CrowdStrikeOpenAPI.yml +++ b/Packs/CrowdStrikeOpenAPI/Integrations/CrowdStrikeOpenAPI/CrowdStrikeOpenAPI.yml @@ -25717,7 +25717,7 @@ script: - contextPath: CrowdStrike.deviceNetworkHistory.resources.history.timestamp description: '' type: String - dockerimage: demisto/python3:3.10.13.85667 + dockerimage: demisto/python3:3.10.13.86272 runonce: false script: '-' subtype: python3 diff --git a/Packs/CrowdStrikeOpenAPI/ReleaseNotes/1_0_18.md b/Packs/CrowdStrikeOpenAPI/ReleaseNotes/1_0_18.md new file mode 100644 index 000000000000..e5a9937d5915 --- /dev/null +++ b/Packs/CrowdStrikeOpenAPI/ReleaseNotes/1_0_18.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### CrowdStrike OpenAPI (Beta) + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/CrowdStrikeOpenAPI/pack_metadata.json b/Packs/CrowdStrikeOpenAPI/pack_metadata.json index 571ae0d4efd0..8532b718ccb2 100644 --- a/Packs/CrowdStrikeOpenAPI/pack_metadata.json +++ b/Packs/CrowdStrikeOpenAPI/pack_metadata.json @@ -2,7 +2,7 @@ "name": "CrowdStrike OpenAPI", "description": "Use the CrowdStrike OpenAPI integration to interact with CrowdStrike APIs that do not have dedicated integrations in Cortex XSOAR, for example, CrowdStrike FalconX, etc.", "support": "xsoar", - "currentVersion": "1.0.17", + "currentVersion": "1.0.18", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CuckooSandbox/ReleaseNotes/1_1_5.md b/Packs/CuckooSandbox/ReleaseNotes/1_1_5.md new file mode 100644 index 000000000000..2acdb56852db --- /dev/null +++ b/Packs/CuckooSandbox/ReleaseNotes/1_1_5.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### CuckooDisplayReport + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/CuckooSandbox/Scripts/CuckooDisplayReport/CuckooDisplayReport.yml b/Packs/CuckooSandbox/Scripts/CuckooDisplayReport/CuckooDisplayReport.yml index cd30cff49f3e..67c3760b8b8b 100644 --- a/Packs/CuckooSandbox/Scripts/CuckooDisplayReport/CuckooDisplayReport.yml +++ b/Packs/CuckooSandbox/Scripts/CuckooDisplayReport/CuckooDisplayReport.yml @@ -22,6 +22,6 @@ args: scripttarget: 0 timeout: 0s fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 tests: - No tests (auto formatted) diff --git a/Packs/CuckooSandbox/pack_metadata.json b/Packs/CuckooSandbox/pack_metadata.json index ffe88b8bdaf7..bf60908e2232 100644 --- a/Packs/CuckooSandbox/pack_metadata.json +++ b/Packs/CuckooSandbox/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cuckoo Sandbox", "description": "Malware dynamic analysis sandboxing", "support": "xsoar", - "currentVersion": "1.1.4", + "currentVersion": "1.1.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/DBotTruthBombs/Integrations/DBotTruthBombs/DBotTruthBombs.yml b/Packs/DBotTruthBombs/Integrations/DBotTruthBombs/DBotTruthBombs.yml index fe77d06d7421..8207258cef63 100644 --- a/Packs/DBotTruthBombs/Integrations/DBotTruthBombs/DBotTruthBombs.yml +++ b/Packs/DBotTruthBombs/Integrations/DBotTruthBombs/DBotTruthBombs.yml @@ -33,7 +33,7 @@ script: - Travel description: Returns a previously undisclosed fact about DBot. name: dbot-truth-bomb - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 runonce: false script: '' subtype: python3 diff --git a/Packs/DBotTruthBombs/ReleaseNotes/1_0_8.md b/Packs/DBotTruthBombs/ReleaseNotes/1_0_8.md new file mode 100644 index 000000000000..f678aff3042c --- /dev/null +++ b/Packs/DBotTruthBombs/ReleaseNotes/1_0_8.md @@ -0,0 +1,12 @@ + +#### Integrations + +##### DBot Truth Bombs + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. + +#### Scripts + +##### FactAboutYou + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/DBotTruthBombs/Scripts/FactsAboutYou/FactsAboutYou.yml b/Packs/DBotTruthBombs/Scripts/FactsAboutYou/FactsAboutYou.yml index 808477108386..a1134f372441 100644 --- a/Packs/DBotTruthBombs/Scripts/FactsAboutYou/FactsAboutYou.yml +++ b/Packs/DBotTruthBombs/Scripts/FactsAboutYou/FactsAboutYou.yml @@ -16,7 +16,7 @@ comment: Reveal some facts about yourself. commonfields: id: FactAboutYou version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: FactAboutYou runas: DBotWeakRole diff --git a/Packs/DBotTruthBombs/pack_metadata.json b/Packs/DBotTruthBombs/pack_metadata.json index 37d586f3790a..0d81f17a4795 100644 --- a/Packs/DBotTruthBombs/pack_metadata.json +++ b/Packs/DBotTruthBombs/pack_metadata.json @@ -2,7 +2,7 @@ "name": "DBot Truth Bombs", "description": "Nefarious attackers coming in at you from all fronts. Don't you wish you could just go Texas Ranger on them?", "support": "xsoar", - "currentVersion": "1.0.7", + "currentVersion": "1.0.8", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/EasyVista/Integrations/EasyVista/EasyVista.yml b/Packs/EasyVista/Integrations/EasyVista/EasyVista.yml index e03205403268..dba4b5529a04 100644 --- a/Packs/EasyVista/Integrations/EasyVista/EasyVista.yml +++ b/Packs/EasyVista/Integrations/EasyVista/EasyVista.yml @@ -134,7 +134,7 @@ script: description: Request ID type: string description: This method allows a list of incidents / requests (service, change, investment) to be obtained. - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 tests: - No tests fromversion: 5.0.0 diff --git a/Packs/EasyVista/ReleaseNotes/1_0_9.md b/Packs/EasyVista/ReleaseNotes/1_0_9.md new file mode 100644 index 000000000000..65e1794b396e --- /dev/null +++ b/Packs/EasyVista/ReleaseNotes/1_0_9.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### EasyVista + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/EasyVista/pack_metadata.json b/Packs/EasyVista/pack_metadata.json index b5f844592d64..043a20ed9467 100644 --- a/Packs/EasyVista/pack_metadata.json +++ b/Packs/EasyVista/pack_metadata.json @@ -2,7 +2,7 @@ "name": "EasyVista", "description": "EasyVista Service Manager manages the entire process of designing, managing and delivering IT services.", "support": "xsoar", - "currentVersion": "1.0.8", + "currentVersion": "1.0.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FeedAlienVault/Integrations/FeedAlienVaultReputation/FeedAlienVaultReputation.yml b/Packs/FeedAlienVault/Integrations/FeedAlienVaultReputation/FeedAlienVaultReputation.yml index 98c3834f56cb..2982e6157434 100644 --- a/Packs/FeedAlienVault/Integrations/FeedAlienVaultReputation/FeedAlienVaultReputation.yml +++ b/Packs/FeedAlienVault/Integrations/FeedAlienVaultReputation/FeedAlienVaultReputation.yml @@ -93,7 +93,7 @@ script: name: indicator_type description: Gets the feed indicators. name: alienvault-get-indicators - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 feed: true runonce: false script: '-' diff --git a/Packs/FeedAlienVault/ReleaseNotes/1_1_30.md b/Packs/FeedAlienVault/ReleaseNotes/1_1_30.md new file mode 100644 index 000000000000..1bc009815f81 --- /dev/null +++ b/Packs/FeedAlienVault/ReleaseNotes/1_1_30.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### AlienVault Reputation Feed + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/FeedAlienVault/pack_metadata.json b/Packs/FeedAlienVault/pack_metadata.json index 6387ef2415a4..ef1e1c59ed35 100644 --- a/Packs/FeedAlienVault/pack_metadata.json +++ b/Packs/FeedAlienVault/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AlienVault Feed", "description": "Indicators feed from AlienVault", "support": "xsoar", - "currentVersion": "1.1.29", + "currentVersion": "1.1.30", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FeedMajesticMillion/Integrations/MajesticMillion/MajesticMillion.yml b/Packs/FeedMajesticMillion/Integrations/MajesticMillion/MajesticMillion.yml index 12add95ae031..d1dcfee8fcd4 100644 --- a/Packs/FeedMajesticMillion/Integrations/MajesticMillion/MajesticMillion.yml +++ b/Packs/FeedMajesticMillion/Integrations/MajesticMillion/MajesticMillion.yml @@ -101,7 +101,7 @@ script: name: limit description: Gets the feed indicators. name: majesticmillion-get-indicators - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 feed: true runonce: false script: '-' diff --git a/Packs/FeedMajesticMillion/ReleaseNotes/1_1_14.md b/Packs/FeedMajesticMillion/ReleaseNotes/1_1_14.md new file mode 100644 index 000000000000..46c589f32578 --- /dev/null +++ b/Packs/FeedMajesticMillion/ReleaseNotes/1_1_14.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Majestic Million Feed + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/FeedMajesticMillion/pack_metadata.json b/Packs/FeedMajesticMillion/pack_metadata.json index ca2e57702138..d9ba5fa9ad0e 100644 --- a/Packs/FeedMajesticMillion/pack_metadata.json +++ b/Packs/FeedMajesticMillion/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Majestic Million Feed", "description": "Use the Majestic Million pack to ingest the top known websites as 'good' indicators.", "support": "xsoar", - "currentVersion": "1.1.13", + "currentVersion": "1.1.14", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FeedTorExitAddresses/Integrations/FeedTorExitAddresses/FeedTorExitAddresses.yml b/Packs/FeedTorExitAddresses/Integrations/FeedTorExitAddresses/FeedTorExitAddresses.yml index 340823c9a693..4b563191e270 100644 --- a/Packs/FeedTorExitAddresses/Integrations/FeedTorExitAddresses/FeedTorExitAddresses.yml +++ b/Packs/FeedTorExitAddresses/Integrations/FeedTorExitAddresses/FeedTorExitAddresses.yml @@ -91,7 +91,7 @@ script: name: limit description: Gets the feed indicators. name: tor-get-indicators - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 feed: true runonce: false script: '-' diff --git a/Packs/FeedTorExitAddresses/ReleaseNotes/1_0_9.md b/Packs/FeedTorExitAddresses/ReleaseNotes/1_0_9.md new file mode 100644 index 000000000000..d34543ab6691 --- /dev/null +++ b/Packs/FeedTorExitAddresses/ReleaseNotes/1_0_9.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Tor Exit Addresses Feed + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/FeedTorExitAddresses/pack_metadata.json b/Packs/FeedTorExitAddresses/pack_metadata.json index 49203a751b95..bf95329d17d4 100644 --- a/Packs/FeedTorExitAddresses/pack_metadata.json +++ b/Packs/FeedTorExitAddresses/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Tor Exit Addresses Feed", "description": "Tor is free software and an open network that helps you defend against\n traffic analysis, a form of network surveillance that threatens personal freedom\n and privacy, confidential business activities and relationships, and state security.", "support": "xsoar", - "currentVersion": "1.0.8", + "currentVersion": "1.0.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Feedsslabusech/Integrations/Feedsslabusech/Feedsslabusech.yml b/Packs/Feedsslabusech/Integrations/Feedsslabusech/Feedsslabusech.yml index 75b3ccf02e53..abc476c5cd4e 100644 --- a/Packs/Feedsslabusech/Integrations/Feedsslabusech/Feedsslabusech.yml +++ b/Packs/Feedsslabusech/Integrations/Feedsslabusech/Feedsslabusech.yml @@ -107,7 +107,7 @@ script: name: indicator_type description: Gets the feed indicators. name: sslbl-get-indicators - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 feed: true runonce: false script: '-' diff --git a/Packs/Feedsslabusech/ReleaseNotes/1_1_26.md b/Packs/Feedsslabusech/ReleaseNotes/1_1_26.md new file mode 100644 index 000000000000..057bf26b8a78 --- /dev/null +++ b/Packs/Feedsslabusech/ReleaseNotes/1_1_26.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### abuse.ch SSL Blacklist Feed + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Feedsslabusech/pack_metadata.json b/Packs/Feedsslabusech/pack_metadata.json index bf594313ec31..5a2911df2b55 100644 --- a/Packs/Feedsslabusech/pack_metadata.json +++ b/Packs/Feedsslabusech/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Abuse.ch SSL Blacklist Feed", "description": "The SSL IP Blacklist contains all hosts (IP addresses) that SSLBL has seen in the past 30 days and\n identified as being associated with a malicious SSL certificate.", "support": "xsoar", - "currentVersion": "1.1.25", + "currentVersion": "1.1.26", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FidelisEndpoint/Integrations/FidelisEndpoint/FidelisEndpoint.yml b/Packs/FidelisEndpoint/Integrations/FidelisEndpoint/FidelisEndpoint.yml index 4f22a30be38e..459499870939 100644 --- a/Packs/FidelisEndpoint/Integrations/FidelisEndpoint/FidelisEndpoint.yml +++ b/Packs/FidelisEndpoint/Integrations/FidelisEndpoint/FidelisEndpoint.yml @@ -1243,7 +1243,7 @@ script: - contextPath: FidelisEndpoint.Query.EntityType description: Entity type. type: Number - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 isfetch: true runonce: false script: '-' diff --git a/Packs/FidelisEndpoint/ReleaseNotes/1_0_6.md b/Packs/FidelisEndpoint/ReleaseNotes/1_0_6.md new file mode 100644 index 000000000000..438a10e86416 --- /dev/null +++ b/Packs/FidelisEndpoint/ReleaseNotes/1_0_6.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Fidelis EDR + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/FidelisEndpoint/pack_metadata.json b/Packs/FidelisEndpoint/pack_metadata.json index 113d1de0925c..6c0b74b0046a 100644 --- a/Packs/FidelisEndpoint/pack_metadata.json +++ b/Packs/FidelisEndpoint/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Fidelis Endpoint", "description": "Fidelis Endpoint", "support": "xsoar", - "currentVersion": "1.0.5", + "currentVersion": "1.0.6", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FiltersAndTransformers/ReleaseNotes/1_2_61.md b/Packs/FiltersAndTransformers/ReleaseNotes/1_2_61.md new file mode 100644 index 000000000000..d7050d95512c --- /dev/null +++ b/Packs/FiltersAndTransformers/ReleaseNotes/1_2_61.md @@ -0,0 +1,12 @@ + +#### Scripts + +##### DT + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### StripChars + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### GetValuesOfMultipleFields + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/FiltersAndTransformers/Scripts/DT/DT.yml b/Packs/FiltersAndTransformers/Scripts/DT/DT.yml index e08cdcf94382..26185d1ec414 100644 --- a/Packs/FiltersAndTransformers/Scripts/DT/DT.yml +++ b/Packs/FiltersAndTransformers/Scripts/DT/DT.yml @@ -21,4 +21,4 @@ scripttarget: 0 tests: - No tests - script used for testing fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 diff --git a/Packs/FiltersAndTransformers/Scripts/GetValuesOfMultipleFIelds/GetValuesOfMultipleFIelds.yml b/Packs/FiltersAndTransformers/Scripts/GetValuesOfMultipleFIelds/GetValuesOfMultipleFIelds.yml index 086899ca1335..ad217a264452 100644 --- a/Packs/FiltersAndTransformers/Scripts/GetValuesOfMultipleFIelds/GetValuesOfMultipleFIelds.yml +++ b/Packs/FiltersAndTransformers/Scripts/GetValuesOfMultipleFIelds/GetValuesOfMultipleFIelds.yml @@ -14,7 +14,7 @@ commonfields: name: GetValuesOfMultipleFields scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole script: '-' tags: diff --git a/Packs/FiltersAndTransformers/Scripts/StripChar/StripChar.yml b/Packs/FiltersAndTransformers/Scripts/StripChar/StripChar.yml index 0b7ad59df4d1..35256123626b 100644 --- a/Packs/FiltersAndTransformers/Scripts/StripChar/StripChar.yml +++ b/Packs/FiltersAndTransformers/Scripts/StripChar/StripChar.yml @@ -23,4 +23,4 @@ subtype: python3 tests: - stripChars - Test fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 diff --git a/Packs/FiltersAndTransformers/pack_metadata.json b/Packs/FiltersAndTransformers/pack_metadata.json index 5758b55b6a3e..32a16f933fab 100644 --- a/Packs/FiltersAndTransformers/pack_metadata.json +++ b/Packs/FiltersAndTransformers/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Filters And Transformers", "description": "Frequently used filters and transformers pack.", "support": "xsoar", - "currentVersion": "1.2.60", + "currentVersion": "1.2.61", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Forescout/Integrations/Forescout/Forescout.yml b/Packs/Forescout/Integrations/Forescout/Forescout.yml index 55f2156e0e11..5dd4129121ad 100644 --- a/Packs/Forescout/Integrations/Forescout/Forescout.yml +++ b/Packs/Forescout/Integrations/Forescout/Forescout.yml @@ -331,7 +331,7 @@ script: name: values description: Update Forescout lists. name: forescout-update-lists - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 runonce: false script: '-' type: python diff --git a/Packs/Forescout/ReleaseNotes/1_0_9.md b/Packs/Forescout/ReleaseNotes/1_0_9.md new file mode 100644 index 000000000000..ea7ba4e85f51 --- /dev/null +++ b/Packs/Forescout/ReleaseNotes/1_0_9.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Forescout CounterACT + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Forescout/pack_metadata.json b/Packs/Forescout/pack_metadata.json index a30e8b993065..02982640d35a 100644 --- a/Packs/Forescout/pack_metadata.json +++ b/Packs/Forescout/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Forescout CounterACT", "description": "Unified device visibility and control platform for IT and OT Security.", "support": "xsoar", - "currentVersion": "1.0.8", + "currentVersion": "1.0.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Imperva_WAF/Integrations/ImpervaWAF/ImpervaWAF.yml b/Packs/Imperva_WAF/Integrations/ImpervaWAF/ImpervaWAF.yml index 60431acc3e32..d62d7a4b2fa2 100644 --- a/Packs/Imperva_WAF/Integrations/ImpervaWAF/ImpervaWAF.yml +++ b/Packs/Imperva_WAF/Integrations/ImpervaWAF/ImpervaWAF.yml @@ -507,7 +507,7 @@ script: required: true description: Deletes a web service custom policy indicated by the policy name. name: imperva-waf-web-service-custom-policy-delete - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 runonce: false script: '-' subtype: python3 diff --git a/Packs/Imperva_WAF/ReleaseNotes/1_0_18.md b/Packs/Imperva_WAF/ReleaseNotes/1_0_18.md new file mode 100644 index 000000000000..8a8c5f011ff7 --- /dev/null +++ b/Packs/Imperva_WAF/ReleaseNotes/1_0_18.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Imperva WAF + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Imperva_WAF/pack_metadata.json b/Packs/Imperva_WAF/pack_metadata.json index 0c91ef785d2d..27381bf0e217 100644 --- a/Packs/Imperva_WAF/pack_metadata.json +++ b/Packs/Imperva_WAF/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Imperva WAF", "description": "Use the Imperva WAF integration to manage IP groups and Web security policies in Imperva WAF.", "support": "xsoar", - "currentVersion": "1.0.17", + "currentVersion": "1.0.18", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/IvantiHeat/Integrations/IvantiHeat/IvantiHeat.yml b/Packs/IvantiHeat/Integrations/IvantiHeat/IvantiHeat.yml index bda42fa5d538..f6bc9949764f 100644 --- a/Packs/IvantiHeat/Integrations/IvantiHeat/IvantiHeat.yml +++ b/Packs/IvantiHeat/Integrations/IvantiHeat/IvantiHeat.yml @@ -280,7 +280,7 @@ script: - contextPath: IvantiHeat.incidents.Email description: Incident owner email address. type: String - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 isfetch: true runonce: false script: '-' diff --git a/Packs/IvantiHeat/ReleaseNotes/1_0_10.md b/Packs/IvantiHeat/ReleaseNotes/1_0_10.md new file mode 100644 index 000000000000..ba8b0d3e6dfd --- /dev/null +++ b/Packs/IvantiHeat/ReleaseNotes/1_0_10.md @@ -0,0 +1,18 @@ + +#### Integrations + +##### Ivanti Heat + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. + +#### Scripts + +##### IvantiHeatCreateIncidentExample + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### IvantiHeatCloseIncidentExample + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### IvantiHeatCreateProblemExample + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/IvantiHeat/Scripts/IvantiHeatCloseIncidentExample/IvantiHeatCloseIncidentExample.yml b/Packs/IvantiHeat/Scripts/IvantiHeatCloseIncidentExample/IvantiHeatCloseIncidentExample.yml index 1761b20d78a0..e1fa28fa9ff8 100644 --- a/Packs/IvantiHeat/Scripts/IvantiHeatCloseIncidentExample/IvantiHeatCloseIncidentExample.yml +++ b/Packs/IvantiHeat/Scripts/IvantiHeatCloseIncidentExample/IvantiHeatCloseIncidentExample.yml @@ -13,7 +13,7 @@ args: description: Incident object ID. scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 tests: diff --git a/Packs/IvantiHeat/Scripts/IvantiHeatCreateIncidentExample/IvantiHeatCreateIncidentExample.yml b/Packs/IvantiHeat/Scripts/IvantiHeatCreateIncidentExample/IvantiHeatCreateIncidentExample.yml index deb2c9ade622..7b0295092725 100644 --- a/Packs/IvantiHeat/Scripts/IvantiHeatCreateIncidentExample/IvantiHeatCreateIncidentExample.yml +++ b/Packs/IvantiHeat/Scripts/IvantiHeatCreateIncidentExample/IvantiHeatCreateIncidentExample.yml @@ -31,7 +31,7 @@ args: description: Incident customer. scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 tests: diff --git a/Packs/IvantiHeat/Scripts/IvantiHeatCreateProblemExample/IvantiHeatCreateProblemExample.yml b/Packs/IvantiHeat/Scripts/IvantiHeatCreateProblemExample/IvantiHeatCreateProblemExample.yml index e8c7937dc0f7..4dcebe199ebc 100644 --- a/Packs/IvantiHeat/Scripts/IvantiHeatCreateProblemExample/IvantiHeatCreateProblemExample.yml +++ b/Packs/IvantiHeat/Scripts/IvantiHeatCreateProblemExample/IvantiHeatCreateProblemExample.yml @@ -28,7 +28,7 @@ args: description: Problem description. scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 tests: diff --git a/Packs/IvantiHeat/pack_metadata.json b/Packs/IvantiHeat/pack_metadata.json index 628989fcfaf3..7d3b01b26a93 100644 --- a/Packs/IvantiHeat/pack_metadata.json +++ b/Packs/IvantiHeat/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Ivanti Heat", "description": "Use Ivanti Heat integration to manage issues and create Demisto incidents from ivanti.", "support": "xsoar", - "currentVersion": "1.0.9", + "currentVersion": "1.0.10", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/LogRhythmRest/Integrations/LogRhythmRest/LogRhythmRest.yml b/Packs/LogRhythmRest/Integrations/LogRhythmRest/LogRhythmRest.yml index a8a4cc88f803..73b07189378c 100644 --- a/Packs/LogRhythmRest/Integrations/LogRhythmRest/LogRhythmRest.yml +++ b/Packs/LogRhythmRest/Integrations/LogRhythmRest/LogRhythmRest.yml @@ -1880,7 +1880,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 tests: - LogRhythm REST test fromversion: 5.0.0 diff --git a/Packs/LogRhythmRest/ReleaseNotes/2_0_22.md b/Packs/LogRhythmRest/ReleaseNotes/2_0_22.md new file mode 100644 index 000000000000..b043319e0e9d --- /dev/null +++ b/Packs/LogRhythmRest/ReleaseNotes/2_0_22.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### LogRhythmRest + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/LogRhythmRest/pack_metadata.json b/Packs/LogRhythmRest/pack_metadata.json index 221ce977df7e..268982492041 100644 --- a/Packs/LogRhythmRest/pack_metadata.json +++ b/Packs/LogRhythmRest/pack_metadata.json @@ -2,7 +2,7 @@ "name": "LogRhythm", "description": "LogRhythm security intelligence.", "support": "xsoar", - "currentVersion": "2.0.21", + "currentVersion": "2.0.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/ML/ReleaseNotes/1_4_10.md b/Packs/ML/ReleaseNotes/1_4_10.md new file mode 100644 index 000000000000..f545b94b1225 --- /dev/null +++ b/Packs/ML/ReleaseNotes/1_4_10.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### ExtendQueryBasedOnPhishingLabels + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/ML/Scripts/ExtendQueryBasedOnPhishingLabels/ExtendQueryBasedOnPhishingLabels.yml b/Packs/ML/Scripts/ExtendQueryBasedOnPhishingLabels/ExtendQueryBasedOnPhishingLabels.yml index d07179b8bf6a..3362a20b5e2d 100644 --- a/Packs/ML/Scripts/ExtendQueryBasedOnPhishingLabels/ExtendQueryBasedOnPhishingLabels.yml +++ b/Packs/ML/Scripts/ExtendQueryBasedOnPhishingLabels/ExtendQueryBasedOnPhishingLabels.yml @@ -23,7 +23,7 @@ tags: - ml timeout: '0' type: python -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 tests: diff --git a/Packs/ML/pack_metadata.json b/Packs/ML/pack_metadata.json index d7f87bfafbb7..4ac67ca6f356 100644 --- a/Packs/ML/pack_metadata.json +++ b/Packs/ML/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Machine Learning", "description": "Help to manage machine learning models in Cortex XSOAR", "support": "xsoar", - "currentVersion": "1.4.9", + "currentVersion": "1.4.10", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MajorBreachesInvestigationandResponse/ReleaseNotes/1_6_37.md b/Packs/MajorBreachesInvestigationandResponse/ReleaseNotes/1_6_37.md new file mode 100644 index 000000000000..ec9b60f12d75 --- /dev/null +++ b/Packs/MajorBreachesInvestigationandResponse/ReleaseNotes/1_6_37.md @@ -0,0 +1,27 @@ + +#### Scripts + +##### RapidBreachResponse-MitigationTasksCount-Widget + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### RapidBreachResponse-CompletedTasksCount-Widget + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### RapidBreachResponse-RemediationTasksCount-Widget + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### RapidBreachResponse-HuntingTasksCount-Widget + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### RapidBreachResponse-TotalIndicatorCount-Widget + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### RapidBreachResponse-EradicationTasksCount-Widget + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### RapidBreachResponse-RemainingTasksCount-Widget + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### RapidBreachResponse-TotalTasksCount-Widget + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseCompletedTasksCountWidget/RapidBreachResponseCompletedTasksCountWidget.yml b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseCompletedTasksCountWidget/RapidBreachResponseCompletedTasksCountWidget.yml index 42365f6ea0f9..1285d16a05f4 100644 --- a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseCompletedTasksCountWidget/RapidBreachResponseCompletedTasksCountWidget.yml +++ b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseCompletedTasksCountWidget/RapidBreachResponseCompletedTasksCountWidget.yml @@ -1,7 +1,7 @@ commonfields: id: RapidBreachResponse-CompletedTasksCount-Widget version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: RapidBreachResponse-CompletedTasksCount-Widget runas: DBotWeakRole diff --git a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseEradicationTasksCountWidget/RapidBreachResponseEradicationTasksCountWidget.yml b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseEradicationTasksCountWidget/RapidBreachResponseEradicationTasksCountWidget.yml index d70c66e99c89..e76db2ada9fa 100644 --- a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseEradicationTasksCountWidget/RapidBreachResponseEradicationTasksCountWidget.yml +++ b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseEradicationTasksCountWidget/RapidBreachResponseEradicationTasksCountWidget.yml @@ -1,7 +1,7 @@ commonfields: id: RapidBreachResponse-EradicationTasksCount-Widget version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: RapidBreachResponse-EradicationTasksCount-Widget runas: DBotWeakRole diff --git a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseHuntingTasksCountWidget/RapidBreachResponseHuntingTasksCountWidget.yml b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseHuntingTasksCountWidget/RapidBreachResponseHuntingTasksCountWidget.yml index 5811ad89874c..a566e8fd2f15 100644 --- a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseHuntingTasksCountWidget/RapidBreachResponseHuntingTasksCountWidget.yml +++ b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseHuntingTasksCountWidget/RapidBreachResponseHuntingTasksCountWidget.yml @@ -1,7 +1,7 @@ commonfields: id: RapidBreachResponse-HuntingTasksCount-Widget version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: RapidBreachResponse-HuntingTasksCount-Widget runas: DBotWeakRole diff --git a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseMitigationTasksCountWidget/RapidBreachResponseMitigationTasksCountWidget.yml b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseMitigationTasksCountWidget/RapidBreachResponseMitigationTasksCountWidget.yml index 64260b58cb7b..43b7d0591b2a 100644 --- a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseMitigationTasksCountWidget/RapidBreachResponseMitigationTasksCountWidget.yml +++ b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseMitigationTasksCountWidget/RapidBreachResponseMitigationTasksCountWidget.yml @@ -1,7 +1,7 @@ commonfields: id: RapidBreachResponse-MitigationTasksCount-Widget version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: RapidBreachResponse-MitigationTasksCount-Widget runas: DBotWeakRole diff --git a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseRemainingTasksCountWidget/RapidBreachResponseRemainingTasksCountWidget.yml b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseRemainingTasksCountWidget/RapidBreachResponseRemainingTasksCountWidget.yml index 34946ac03cf2..f367ca8026e8 100644 --- a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseRemainingTasksCountWidget/RapidBreachResponseRemainingTasksCountWidget.yml +++ b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseRemainingTasksCountWidget/RapidBreachResponseRemainingTasksCountWidget.yml @@ -1,7 +1,7 @@ commonfields: id: RapidBreachResponse-RemainingTasksCount-Widget version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: RapidBreachResponse-RemainingTasksCount-Widget runas: DBotWeakRole diff --git a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseRemediationTasksCountWidget/RapidBreachResponseRemediationTasksCountWidget.yml b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseRemediationTasksCountWidget/RapidBreachResponseRemediationTasksCountWidget.yml index 524eb20c355a..3c1d3506f17c 100644 --- a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseRemediationTasksCountWidget/RapidBreachResponseRemediationTasksCountWidget.yml +++ b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseRemediationTasksCountWidget/RapidBreachResponseRemediationTasksCountWidget.yml @@ -1,7 +1,7 @@ commonfields: id: RapidBreachResponse-RemediationTasksCount-Widget version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: RapidBreachResponse-RemediationTasksCount-Widget runas: DBotWeakRole diff --git a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseTotalIndicatorCountWidget/RapidBreachResponseTotalIndicatorCountWidget.yml b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseTotalIndicatorCountWidget/RapidBreachResponseTotalIndicatorCountWidget.yml index dc392ae26351..ac4104e3a859 100644 --- a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseTotalIndicatorCountWidget/RapidBreachResponseTotalIndicatorCountWidget.yml +++ b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseTotalIndicatorCountWidget/RapidBreachResponseTotalIndicatorCountWidget.yml @@ -1,7 +1,7 @@ commonfields: id: RapidBreachResponse-TotalIndicatorCount-Widget version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: RapidBreachResponse-TotalIndicatorCount-Widget runas: DBotWeakRole diff --git a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseTotalTasksCountWidget/RapidBreachResponseTotalTasksCountWidget.yml b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseTotalTasksCountWidget/RapidBreachResponseTotalTasksCountWidget.yml index 01958b60ec21..4c74f82d6fd0 100644 --- a/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseTotalTasksCountWidget/RapidBreachResponseTotalTasksCountWidget.yml +++ b/Packs/MajorBreachesInvestigationandResponse/Scripts/RapidBreachResponseTotalTasksCountWidget/RapidBreachResponseTotalTasksCountWidget.yml @@ -1,7 +1,7 @@ commonfields: id: RapidBreachResponse-TotalTasksCount-Widget version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: RapidBreachResponse-TotalTasksCount-Widget runas: DBotWeakRole diff --git a/Packs/MajorBreachesInvestigationandResponse/pack_metadata.json b/Packs/MajorBreachesInvestigationandResponse/pack_metadata.json index e3c526552258..d86e39ab9552 100644 --- a/Packs/MajorBreachesInvestigationandResponse/pack_metadata.json +++ b/Packs/MajorBreachesInvestigationandResponse/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Rapid Breach Response", "description": "This content Pack helps you collect, investigate, and remediate incidents related to major breaches.", "support": "xsoar", - "currentVersion": "1.6.36", + "currentVersion": "1.6.37", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Microsoft365Defender/ReleaseNotes/4_5_17.md b/Packs/Microsoft365Defender/ReleaseNotes/4_5_17.md new file mode 100644 index 000000000000..f7e4d0409fe1 --- /dev/null +++ b/Packs/Microsoft365Defender/ReleaseNotes/4_5_17.md @@ -0,0 +1,9 @@ + +#### Scripts + +##### MS365DefenderUserListToTable + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### MS365DefenderCountIncidentCategories + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Microsoft365Defender/Scripts/MS365DefenderCountIncidentCategories/MS365DefenderCountIncidentCategories.yml b/Packs/Microsoft365Defender/Scripts/MS365DefenderCountIncidentCategories/MS365DefenderCountIncidentCategories.yml index a90fff2b3970..e0c6b9286a01 100644 --- a/Packs/Microsoft365Defender/Scripts/MS365DefenderCountIncidentCategories/MS365DefenderCountIncidentCategories.yml +++ b/Packs/Microsoft365Defender/Scripts/MS365DefenderCountIncidentCategories/MS365DefenderCountIncidentCategories.yml @@ -5,7 +5,7 @@ comment: count the categories of alerts in given incident commonfields: id: MS365DefenderCountIncidentCategories version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: MS365DefenderCountIncidentCategories runas: DBotWeakRole diff --git a/Packs/Microsoft365Defender/Scripts/MS365DefenderUserListToTable/MS365DefenderUserListToTable.yml b/Packs/Microsoft365Defender/Scripts/MS365DefenderUserListToTable/MS365DefenderUserListToTable.yml index 9e419a2d3fa8..a9ae8ed2199f 100644 --- a/Packs/Microsoft365Defender/Scripts/MS365DefenderUserListToTable/MS365DefenderUserListToTable.yml +++ b/Packs/Microsoft365Defender/Scripts/MS365DefenderUserListToTable/MS365DefenderUserListToTable.yml @@ -4,7 +4,7 @@ args: commonfields: id: MS365DefenderUserListToTable version: -1 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 enabled: true name: MS365DefenderUserListToTable runas: DBotWeakRole diff --git a/Packs/Microsoft365Defender/pack_metadata.json b/Packs/Microsoft365Defender/pack_metadata.json index 606f0a02a00f..6c12fe360418 100644 --- a/Packs/Microsoft365Defender/pack_metadata.json +++ b/Packs/Microsoft365Defender/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft 365 Defender", "description": "Microsoft 365 Defender is a unified pre- and post-breach enterprise defense suite that natively coordinates detection, prevention, investigation, and response across endpoints, identities, email, and applications to provide integrated protection against sophisticated attacks.", "support": "xsoar", - "currentVersion": "4.5.16", + "currentVersion": "4.5.17", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/PrismaAccess/Integrations/PrismaAccessEgressIPFeed/PrismaAccessEgressIPFeed.yml b/Packs/PrismaAccess/Integrations/PrismaAccessEgressIPFeed/PrismaAccessEgressIPFeed.yml index 5f4bbfb66a4f..a82c6007b400 100644 --- a/Packs/PrismaAccess/Integrations/PrismaAccessEgressIPFeed/PrismaAccessEgressIPFeed.yml +++ b/Packs/PrismaAccess/Integrations/PrismaAccessEgressIPFeed/PrismaAccessEgressIPFeed.yml @@ -147,7 +147,7 @@ script: description: Prisma Access Egress IP zone type: string description: Gets indicators from the feed. - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 feed: true subtype: python3 fromversion: 5.5.0 diff --git a/Packs/PrismaAccess/ReleaseNotes/2_1_4.md b/Packs/PrismaAccess/ReleaseNotes/2_1_4.md new file mode 100644 index 000000000000..11d311f40deb --- /dev/null +++ b/Packs/PrismaAccess/ReleaseNotes/2_1_4.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Prisma Access Egress IP feed + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/PrismaAccess/pack_metadata.json b/Packs/PrismaAccess/pack_metadata.json index 9e70b313d833..7d178b703be5 100644 --- a/Packs/PrismaAccess/pack_metadata.json +++ b/Packs/PrismaAccess/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Prisma SASE by Palo Alto Networks", "description": "Integrate with Palo Alto Networks Prisma SASE to query activity and take actions.", "support": "xsoar", - "currentVersion": "2.1.3", + "currentVersion": "2.1.4", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/ProofpointTAP/ReleaseNotes/1_2_11.md b/Packs/ProofpointTAP/ReleaseNotes/1_2_11.md new file mode 100644 index 000000000000..7a9f53f5dd65 --- /dev/null +++ b/Packs/ProofpointTAP/ReleaseNotes/1_2_11.md @@ -0,0 +1,9 @@ + +#### Scripts + +##### ProofpointTapTopClickers + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### ProofpointTAPMostAttackedUsers + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/ProofpointTAP/Scripts/ProofpointTAPMostAttackedUsers/ProofpointTAPMostAttackedUsers.yml b/Packs/ProofpointTAP/Scripts/ProofpointTAPMostAttackedUsers/ProofpointTAPMostAttackedUsers.yml index 49aca6cee352..270e33d24b10 100644 --- a/Packs/ProofpointTAP/Scripts/ProofpointTAPMostAttackedUsers/ProofpointTAPMostAttackedUsers.yml +++ b/Packs/ProofpointTAP/Scripts/ProofpointTAPMostAttackedUsers/ProofpointTAPMostAttackedUsers.yml @@ -10,7 +10,7 @@ enabled: true comment: Exports a list of Proofpoint TAP most attacked users to the Cortex XSOAR widget. scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 tests: diff --git a/Packs/ProofpointTAP/Scripts/ProofpointTapTopClickers/ProofpointTapTopClickers.yml b/Packs/ProofpointTAP/Scripts/ProofpointTapTopClickers/ProofpointTapTopClickers.yml index 4841b0ec3b4d..f2842f8073af 100644 --- a/Packs/ProofpointTAP/Scripts/ProofpointTapTopClickers/ProofpointTapTopClickers.yml +++ b/Packs/ProofpointTAP/Scripts/ProofpointTapTopClickers/ProofpointTapTopClickers.yml @@ -10,7 +10,7 @@ enabled: true comment: Exports a list of Proofpoint TAP top clickers to the Cortex XSOAR widget. scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 tests: diff --git a/Packs/ProofpointTAP/pack_metadata.json b/Packs/ProofpointTAP/pack_metadata.json index 110e0d9a499c..08ee2657e954 100644 --- a/Packs/ProofpointTAP/pack_metadata.json +++ b/Packs/ProofpointTAP/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Proofpoint TAP", "description": "Use the Proofpoint Targeted Attack Protection (TAP) integration to protect against and provide additional visibility into phishing and other malicious email attacks.", "support": "xsoar", - "currentVersion": "1.2.10", + "currentVersion": "1.2.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Salesforce/ReleaseNotes/2_0_23.md b/Packs/Salesforce/ReleaseNotes/2_0_23.md new file mode 100644 index 000000000000..476f6fee1931 --- /dev/null +++ b/Packs/Salesforce/ReleaseNotes/2_0_23.md @@ -0,0 +1,9 @@ + +#### Scripts + +##### generate_profile_id + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### generate_timezonesidkey + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Salesforce/Scripts/GenerateProfileId/GenerateProfileId.yml b/Packs/Salesforce/Scripts/GenerateProfileId/GenerateProfileId.yml index 231c42eca423..0ea76e9b48c8 100644 --- a/Packs/Salesforce/Scripts/GenerateProfileId/GenerateProfileId.yml +++ b/Packs/Salesforce/Scripts/GenerateProfileId/GenerateProfileId.yml @@ -10,7 +10,7 @@ comment: Generate profileId by user data. enabled: true scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.0.0 tests: diff --git a/Packs/Salesforce/Scripts/GenerateTimeZone/GenerateTimeZone.yml b/Packs/Salesforce/Scripts/GenerateTimeZone/GenerateTimeZone.yml index be508870d0f0..2bedf7aaca29 100644 --- a/Packs/Salesforce/Scripts/GenerateTimeZone/GenerateTimeZone.yml +++ b/Packs/Salesforce/Scripts/GenerateTimeZone/GenerateTimeZone.yml @@ -10,7 +10,7 @@ comment: Generate timezonesidkey by user data. enabled: true scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.0.0 tests: diff --git a/Packs/Salesforce/pack_metadata.json b/Packs/Salesforce/pack_metadata.json index e4f039d5904a..a1aea515e7aa 100644 --- a/Packs/Salesforce/pack_metadata.json +++ b/Packs/Salesforce/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Salesforce", "description": "CRM Services", "support": "xsoar", - "currentVersion": "2.0.22", + "currentVersion": "2.0.23", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/ServiceNow/ReleaseNotes/2_5_53.md b/Packs/ServiceNow/ReleaseNotes/2_5_53.md new file mode 100644 index 000000000000..8a27eb04f9a0 --- /dev/null +++ b/Packs/ServiceNow/ReleaseNotes/2_5_53.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### ServiceNowIncidentStatus + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/ServiceNow/Scripts/ServiceNowIncidentStatus/ServiceNowIncidentStatus.yml b/Packs/ServiceNow/Scripts/ServiceNowIncidentStatus/ServiceNowIncidentStatus.yml index f288e4da7712..4c4e284e7459 100644 --- a/Packs/ServiceNow/Scripts/ServiceNowIncidentStatus/ServiceNowIncidentStatus.yml +++ b/Packs/ServiceNow/Scripts/ServiceNowIncidentStatus/ServiceNowIncidentStatus.yml @@ -13,7 +13,7 @@ comment: | enabled: true scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole tests: - No tests (auto formatted) diff --git a/Packs/ServiceNow/pack_metadata.json b/Packs/ServiceNow/pack_metadata.json index b519b2b3771b..24af09c0df5f 100644 --- a/Packs/ServiceNow/pack_metadata.json +++ b/Packs/ServiceNow/pack_metadata.json @@ -2,7 +2,7 @@ "name": "ServiceNow", "description": "Use The ServiceNow IT Service Management (ITSM) solution to modernize the way you manage and deliver services to your users.", "support": "xsoar", - "currentVersion": "2.5.52", + "currentVersion": "2.5.53", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Slack/Integrations/Slack_IAM/Slack_IAM.yml b/Packs/Slack/Integrations/Slack_IAM/Slack_IAM.yml index c33e25bdb486..a8cb48fc834f 100644 --- a/Packs/Slack/Integrations/Slack_IAM/Slack_IAM.yml +++ b/Packs/Slack/Integrations/Slack_IAM/Slack_IAM.yml @@ -356,7 +356,7 @@ script: - contextPath: UpdateGroup.errorMessage description: Reason why the API failed. type: String - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 runonce: false script: '-' subtype: python3 diff --git a/Packs/Slack/ReleaseNotes/3_4_5.md b/Packs/Slack/ReleaseNotes/3_4_5.md new file mode 100644 index 000000000000..9dded9568291 --- /dev/null +++ b/Packs/Slack/ReleaseNotes/3_4_5.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Slack IAM + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Slack/pack_metadata.json b/Packs/Slack/pack_metadata.json index c2729f5e97b6..ec314bf3d144 100644 --- a/Packs/Slack/pack_metadata.json +++ b/Packs/Slack/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Slack", "description": "Interact with Slack API - collect logs, send messages and notifications to your Slack team.", "support": "xsoar", - "currentVersion": "3.4.4", + "currentVersion": "3.4.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Telegram/Integrations/Telegram/Telegram.yml b/Packs/Telegram/Integrations/Telegram/Telegram.yml index b7076b8c78e6..847fa3faab7c 100644 --- a/Packs/Telegram/Integrations/Telegram/Telegram.yml +++ b/Packs/Telegram/Integrations/Telegram/Telegram.yml @@ -36,7 +36,7 @@ script: name: telegram-send-message - description: List users name: telegram-list-users - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 runonce: false script: '-' type: python diff --git a/Packs/Telegram/ReleaseNotes/1_0_8.md b/Packs/Telegram/ReleaseNotes/1_0_8.md new file mode 100644 index 000000000000..be2c7f867505 --- /dev/null +++ b/Packs/Telegram/ReleaseNotes/1_0_8.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Telegram (Beta) + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Telegram/pack_metadata.json b/Packs/Telegram/pack_metadata.json index 3822832b4587..ecb7f29d64b6 100644 --- a/Packs/Telegram/pack_metadata.json +++ b/Packs/Telegram/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Telegram (Beta)", "description": "Telegram integration", "support": "xsoar", - "currentVersion": "1.0.7", + "currentVersion": "1.0.8", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/ThreatIntelReports/ReleaseNotes/1_0_13.md b/Packs/ThreatIntelReports/ReleaseNotes/1_0_13.md new file mode 100644 index 000000000000..1f75c856a909 --- /dev/null +++ b/Packs/ThreatIntelReports/ReleaseNotes/1_0_13.md @@ -0,0 +1,9 @@ + +#### Scripts + +##### UnpublishThreatIntelReport + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### PublishThreatIntelReport + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/ThreatIntelReports/Scripts/PublishThreatIntelReport/PublishThreatIntelReport.yml b/Packs/ThreatIntelReports/Scripts/PublishThreatIntelReport/PublishThreatIntelReport.yml index 76008f94b6b3..735299aa0296 100644 --- a/Packs/ThreatIntelReports/Scripts/PublishThreatIntelReport/PublishThreatIntelReport.yml +++ b/Packs/ThreatIntelReports/Scripts/PublishThreatIntelReport/PublishThreatIntelReport.yml @@ -14,7 +14,7 @@ args: description: The Threat Intel Report object to publish. scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.5.0 tests: diff --git a/Packs/ThreatIntelReports/Scripts/UnpublishThreatIntelReport/UnpublishThreatIntelReport.yml b/Packs/ThreatIntelReports/Scripts/UnpublishThreatIntelReport/UnpublishThreatIntelReport.yml index 0bb31b37fbd5..97e4ba363408 100644 --- a/Packs/ThreatIntelReports/Scripts/UnpublishThreatIntelReport/UnpublishThreatIntelReport.yml +++ b/Packs/ThreatIntelReports/Scripts/UnpublishThreatIntelReport/UnpublishThreatIntelReport.yml @@ -14,7 +14,7 @@ args: description: The Threat Intel Report object to unpublish. scripttarget: 0 subtype: python3 -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 6.5.0 tests: diff --git a/Packs/ThreatIntelReports/pack_metadata.json b/Packs/ThreatIntelReports/pack_metadata.json index cd58b7020853..09f0369edf8b 100644 --- a/Packs/ThreatIntelReports/pack_metadata.json +++ b/Packs/ThreatIntelReports/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Threat Intel Reports (BETA)", "description": "Threat Intel Reports gives the user the ability to create, review, publish, and export threat intelligence reports.", "support": "xsoar", - "currentVersion": "1.0.12", + "currentVersion": "1.0.13", "serverMinVersion": "6.5.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", diff --git a/Packs/ThreatMiner/Integrations/ThreatMiner/ThreatMiner.yml b/Packs/ThreatMiner/Integrations/ThreatMiner/ThreatMiner.yml index 2aef786b6c3c..7e10a8d0d525 100644 --- a/Packs/ThreatMiner/Integrations/ThreatMiner/ThreatMiner.yml +++ b/Packs/ThreatMiner/Integrations/ThreatMiner/ThreatMiner.yml @@ -292,7 +292,7 @@ script: type: string description: Retrieves data from ThreatMiner about a specified file. runonce: false - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 tests: - ThreatMiner-Test fromversion: 5.0.0 diff --git a/Packs/ThreatMiner/ReleaseNotes/1_0_13.md b/Packs/ThreatMiner/ReleaseNotes/1_0_13.md new file mode 100644 index 000000000000..4ba89044cc9f --- /dev/null +++ b/Packs/ThreatMiner/ReleaseNotes/1_0_13.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### ThreatMiner + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/ThreatMiner/pack_metadata.json b/Packs/ThreatMiner/pack_metadata.json index 75fc7b6b59da..84eec9850ca1 100644 --- a/Packs/ThreatMiner/pack_metadata.json +++ b/Packs/ThreatMiner/pack_metadata.json @@ -2,7 +2,7 @@ "name": "ThreatMiner", "description": "Data Mining for Threat Intelligence", "support": "xsoar", - "currentVersion": "1.0.12", + "currentVersion": "1.0.13", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Troubleshoot/ReleaseNotes/2_0_18.md b/Packs/Troubleshoot/ReleaseNotes/2_0_18.md new file mode 100644 index 000000000000..c8222b42ee06 --- /dev/null +++ b/Packs/Troubleshoot/ReleaseNotes/2_0_18.md @@ -0,0 +1,15 @@ + +#### Scripts + +##### TroubleshootGetCommandandArgs + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### TroubleshootAggregateResults + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### TroubleshootExecuteCommand + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. +##### TroubleshootInstanceField + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/Troubleshoot/Scripts/TroubleshootAggregateResults/TroubleshootAggregateResults.yml b/Packs/Troubleshoot/Scripts/TroubleshootAggregateResults/TroubleshootAggregateResults.yml index 6c75b9f5e9da..b94e1f78d4fd 100644 --- a/Packs/Troubleshoot/Scripts/TroubleshootAggregateResults/TroubleshootAggregateResults.yml +++ b/Packs/Troubleshoot/Scripts/TroubleshootAggregateResults/TroubleshootAggregateResults.yml @@ -32,7 +32,7 @@ tags: - troubleshoot timeout: '0' type: python -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 fromversion: 5.0.0 tests: - No tests (auto formatted) diff --git a/Packs/Troubleshoot/Scripts/TroubleshootExecuteCommand/TroubleshootExecuteCommand.yml b/Packs/Troubleshoot/Scripts/TroubleshootExecuteCommand/TroubleshootExecuteCommand.yml index 63e4316eb988..065fa959a2f1 100644 --- a/Packs/Troubleshoot/Scripts/TroubleshootExecuteCommand/TroubleshootExecuteCommand.yml +++ b/Packs/Troubleshoot/Scripts/TroubleshootExecuteCommand/TroubleshootExecuteCommand.yml @@ -58,7 +58,7 @@ tags: - troubleshoot timeout: '0' type: python -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 fromversion: 5.0.0 tests: - No tests (auto formatted) diff --git a/Packs/Troubleshoot/Scripts/TroubleshootGetCommandandArgs/TroubleshootGetCommandandArgs.yml b/Packs/Troubleshoot/Scripts/TroubleshootGetCommandandArgs/TroubleshootGetCommandandArgs.yml index 28d4f48c167b..962621009b60 100644 --- a/Packs/Troubleshoot/Scripts/TroubleshootGetCommandandArgs/TroubleshootGetCommandandArgs.yml +++ b/Packs/Troubleshoot/Scripts/TroubleshootGetCommandandArgs/TroubleshootGetCommandandArgs.yml @@ -27,7 +27,7 @@ tags: - troubleshoot timeout: '0' type: python -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 fromversion: 5.0.0 tests: - No tests (auto formatted) diff --git a/Packs/Troubleshoot/Scripts/TroubleshootInstanceField/TroubleshootInstanceField.yml b/Packs/Troubleshoot/Scripts/TroubleshootInstanceField/TroubleshootInstanceField.yml index efd01e44b744..91a6c5b38c60 100644 --- a/Packs/Troubleshoot/Scripts/TroubleshootInstanceField/TroubleshootInstanceField.yml +++ b/Packs/Troubleshoot/Scripts/TroubleshootInstanceField/TroubleshootInstanceField.yml @@ -10,7 +10,7 @@ enabled: true scripttarget: 0 subtype: python3 comment: Populates the InstanceName field with active instances. -dockerimage: demisto/python3:3.10.12.63474 +dockerimage: demisto/python3:3.10.13.86272 runas: DBotWeakRole fromversion: 5.0.0 tests: diff --git a/Packs/Troubleshoot/pack_metadata.json b/Packs/Troubleshoot/pack_metadata.json index 2a85ac627b3d..d32f6c66be5b 100644 --- a/Packs/Troubleshoot/pack_metadata.json +++ b/Packs/Troubleshoot/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Troubleshoot", "description": "Use this pack to troubleshoot your environment.", "support": "xsoar", - "currentVersion": "2.0.17", + "currentVersion": "2.0.18", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/WhatIsMyBrowser/Integrations/WhatIsMyBrowser/WhatIsMyBrowser.yml b/Packs/WhatIsMyBrowser/Integrations/WhatIsMyBrowser/WhatIsMyBrowser.yml index c0df5bc1f3a5..debe50d1ac45 100644 --- a/Packs/WhatIsMyBrowser/Integrations/WhatIsMyBrowser/WhatIsMyBrowser.yml +++ b/Packs/WhatIsMyBrowser/Integrations/WhatIsMyBrowser/WhatIsMyBrowser.yml @@ -66,7 +66,7 @@ script: type: string description: Parses a User Agent string subtype: python3 - dockerimage: demisto/python3:3.10.12.63474 + dockerimage: demisto/python3:3.10.13.86272 tests: - WhatsMyBrowser-Test fromversion: 5.0.0 diff --git a/Packs/WhatIsMyBrowser/ReleaseNotes/1_0_11.md b/Packs/WhatIsMyBrowser/ReleaseNotes/1_0_11.md new file mode 100644 index 000000000000..0bfe176473d8 --- /dev/null +++ b/Packs/WhatIsMyBrowser/ReleaseNotes/1_0_11.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### WhatIsMyBrowser + +- Updated the Docker image to: *demisto/python3:3.10.13.86272*. diff --git a/Packs/WhatIsMyBrowser/pack_metadata.json b/Packs/WhatIsMyBrowser/pack_metadata.json index 5058d77e08ab..618a6ee15ba0 100644 --- a/Packs/WhatIsMyBrowser/pack_metadata.json +++ b/Packs/WhatIsMyBrowser/pack_metadata.json @@ -2,7 +2,7 @@ "name": "WhatIsMyBrowser", "description": "Parse user agents and determine if they are malicious as well as enrich information about the agent", "support": "xsoar", - "currentVersion": "1.0.10", + "currentVersion": "1.0.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From c757613e8297abe2a669a49a419db983c758beb8 Mon Sep 17 00:00:00 2001 From: Michael Yochpaz <8832013+MichaelYochpaz@users.noreply.github.com> Date: Sun, 18 Feb 2024 15:27:17 +0200 Subject: [PATCH 006/272] [Okta v2] Make API Token Non-required When Using OAuth (#32877) * Make API token optional and non-required when using OAuth * Update documentation * Bump version * pre-commit * Bump pack from version Okta to 3.2.11. * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Bump Docker version * Fix mypy issues * Fix release-notes * Minor documentation improvement * Minor fix --------- Co-authored-by: Content Bot Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- .../Scripts/OktaApiModule/OktaApiModule.py | 74 ++++++------------- .../OktaApiModule/OktaApiModule_test.py | 11 +-- Packs/Okta/Integrations/Okta_v2/Okta_v2.py | 21 ++---- Packs/Okta/Integrations/Okta_v2/Okta_v2.yml | 20 ++--- .../Okta_v2/Okta_v2_description.md | 41 +++++----- Packs/Okta/Integrations/Okta_v2/README.md | 54 +++++++------- Packs/Okta/ReleaseNotes/3_2_11.md | 8 ++ Packs/Okta/pack_metadata.json | 2 +- 8 files changed, 98 insertions(+), 133 deletions(-) create mode 100644 Packs/Okta/ReleaseNotes/3_2_11.md diff --git a/Packs/ApiModules/Scripts/OktaApiModule/OktaApiModule.py b/Packs/ApiModules/Scripts/OktaApiModule/OktaApiModule.py index a6ee4040d4a1..d6e0eb735409 100644 --- a/Packs/ApiModules/Scripts/OktaApiModule/OktaApiModule.py +++ b/Packs/ApiModules/Scripts/OktaApiModule/OktaApiModule.py @@ -1,10 +1,11 @@ from CommonServerPython import * -import jwt import uuid from datetime import datetime, timedelta from enum import Enum +import jwt + TOKEN_EXPIRATION_TIME = 60 # In minutes. This value must be a maximum of only an hour (according to Okta's documentation). TOKEN_RENEWAL_TIME_LIMIT = 60 # In seconds. The minimum time before the token expires to renew it. @@ -26,13 +27,13 @@ class AuthType(Enum): class OktaClient(BaseClient): - def __init__(self, api_token: str, auth_type: AuthType = AuthType.API_TOKEN, + def __init__(self, auth_type: AuthType = AuthType.API_TOKEN, api_token: str | None = None, client_id: str | None = None, scopes: list[str] | None = None, private_key: str | None = None, jwt_algorithm: JWTAlgorithm | None = None, *args, **kwargs): """ Args: - api_token (str): API token for authentication. auth_type (AuthType, optional): The type of authentication to use. + api_token (str | None, optional): API token for authentication (required if 'auth_type' is AuthType.API_TOKEN). client_id (str | None, optional): Client ID for OAuth authentication (required if 'auth_type' is AuthType.OAUTH). scopes (list[str] | None, optional): A list of scopes to request for the token (required if 'auth_type' is AuthType.OAUTH). @@ -41,36 +42,37 @@ def __init__(self, api_token: str, auth_type: AuthType = AuthType.API_TOKEN, (required if 'auth_type' is AuthType.OAUTH). """ super().__init__(*args, **kwargs) - self.api_token = api_token self.auth_type = auth_type + self.api_token = api_token + + self.client_id = client_id + self.scopes = scopes + self.jwt_algorithm = jwt_algorithm + self.private_key = private_key + missing_required_params = [] + if self.auth_type == AuthType.API_TOKEN and not api_token: + raise ValueError('API token is missing') + if self.auth_type == AuthType.OAUTH: - if not client_id: + if not self.client_id: missing_required_params.append('Client ID') - if not scopes: + if not self.scopes: missing_required_params.append('Scopes') - if not jwt_algorithm: + if not self.jwt_algorithm: missing_required_params.append('JWT algorithm') - if not private_key: + if not self.private_key: missing_required_params.append('Private key') if missing_required_params: raise ValueError(f'Required OAuth parameters are missing: {", ".join(missing_required_params)}') - # Set type of variables non-optional after we assured they're assigned for mypy - self.client_id: str = client_id # type: ignore - self.scopes: list[str] = scopes # type: ignore - self.private_key: str = private_key # type: ignore - self.jwt_algorithm: JWTAlgorithm = jwt_algorithm # type: ignore - - self.initial_setup() - - def assign_app_role(self, client_id: str, role: str, auth_type: AuthType = AuthType.API_TOKEN) -> dict: + def assign_app_role(self, client_id: str, role: str, auth_type: AuthType) -> dict: """ Assign a role to a client application. @@ -113,8 +115,8 @@ def generate_jwt_token(self, url: str) -> str: 'sub': self.client_id, 'jti': str(uuid.uuid4()), }, - key=self.private_key, - algorithm=self.jwt_algorithm.value, + key=self.private_key, # type: ignore[arg-type] + algorithm=self.jwt_algorithm.value, # type: ignore[union-attr] ) def generate_oauth_token(self, scopes: list[str]) -> dict: @@ -148,7 +150,7 @@ def generate_oauth_token(self, scopes: list[str]) -> dict: def get_token(self): """ - Get an API token for authentication. + Get an OAuth token for authentication. If there isn't an existing one, or the existing one is expired, a new one will be generated. """ expiration_time_format = '%Y-%m-%dT%H:%M:%S' @@ -170,7 +172,7 @@ def get_token(self): else: demisto.debug('No existing token was found. A new token will be generated.') - token_generation_response = self.generate_oauth_token(scopes=self.scopes) + token_generation_response = self.generate_oauth_token(scopes=self.scopes) # type: ignore[arg-type] token: str = token_generation_response['access_token'] expires_in: int = token_generation_response['expires_in'] token_expiration = datetime.utcnow() + timedelta(seconds=expires_in) @@ -182,36 +184,6 @@ def get_token(self): return token - def initial_setup(self): - """ - Initial setup for the first time the integration is used. - """ - integration_context = get_integration_context() - - if integration_context.get('initialized', False): # If the initial setup was already done, do nothing - return - - if self.auth_type == AuthType.OAUTH: - # Add "SUPER_ADMIN" role to client application, which is required for OAuth authentication - try: - self.assign_app_role(client_id=self.client_id, role="SUPER_ADMIN", auth_type=AuthType.API_TOKEN) - demisto.debug("'SUPER_ADMIN' role has been assigned to the client application.") - - except DemistoException as e: - # If the client application already has the "SUPER_ADMIN" role, ignore the error. - # E0000090 Error code official docs description: Duplicate role assignment exception. - if e.res.headers.get('content-type') == 'application/json' and e.res.json().get('errorCode') == 'E0000090': - demisto.debug('The client application already has the "SUPER_ADMIN" role assigned.') - - else: - raise e - - self.get_token() - - integration_context = get_integration_context() - integration_context['initialized'] = True - set_integration_context(integration_context) - def http_request(self, auth_type: AuthType | None = None, **kwargs): """ Override BaseClient._http_request() to automatically add authentication headers. diff --git a/Packs/ApiModules/Scripts/OktaApiModule/OktaApiModule_test.py b/Packs/ApiModules/Scripts/OktaApiModule/OktaApiModule_test.py index 3b61a355fc19..9f93279f92df 100644 --- a/Packs/ApiModules/Scripts/OktaApiModule/OktaApiModule_test.py +++ b/Packs/ApiModules/Scripts/OktaApiModule/OktaApiModule_test.py @@ -46,7 +46,7 @@ def test_okta_client_no_required_params(): OktaClient( base_url='https://test.url', api_token='X', - auth_type=AuthType.NO_AUTH + auth_type=AuthType.API_TOKEN, ) @@ -56,7 +56,6 @@ def test_assign_app_role(mocker): When: Assigning a role to a client application Then: Assure the call is made properly, and that the 'auth_type' parameter overrides the client's auth type. """ - mocker.patch.object(OktaClient, 'initial_setup') client = OktaClient( base_url='https://test.url', api_token='X', @@ -116,7 +115,6 @@ def test_generate_jwt_token(mocker): When: Generating a JWT token Then: Assure the token is generated correctly. """ - mocker.patch.object(OktaClient, 'initial_setup') client = OktaClient( base_url='https://test.url', api_token='X', @@ -169,7 +167,6 @@ def test_generate_oauth_token(mocker): When: Generating an OAuth token Then: Assure the token generation API call is called correctly. """ - mocker.patch.object(OktaClient, 'initial_setup') client = OktaClient( base_url='https://test.url', api_token='X', @@ -209,7 +206,6 @@ def test_get_token_create_new_token(mocker): Then: Assure a new token is generated, and that the integration context is updated with the new token. """ import OktaApiModule - mocker.patch.object(OktaClient, 'initial_setup') client = OktaClient( # 'initial_setup' is called within the constructor base_url='https://test.url', api_token='X', @@ -240,7 +236,6 @@ def test_get_token_use_existing(mocker): Then: Assure the existing token is returned. """ import OktaApiModule - mocker.patch.object(OktaClient, 'initial_setup') client = OktaClient( # 'initial_setup' is called within the constructor base_url='https://test.url', api_token='X', @@ -264,7 +259,6 @@ def test_get_token_regenerate_existing(mocker): Then: Assure a new token is generated """ import OktaApiModule - mocker.patch.object(OktaClient, 'initial_setup') client = OktaClient( # 'initial_setup' is called within the constructor base_url='https://test.url', api_token='X', @@ -291,7 +285,6 @@ def test_http_request_no_auth(mocker): When: Making an API call with no authentication Then: Assure the call is made without any authentication headers. """ - mocker.patch.object(OktaClient, 'initial_setup') client = OktaClient( base_url='https://test.url', api_token='X', @@ -322,7 +315,6 @@ def test_http_request_api_token_auth(mocker): When: Making an API call with API token authentication Then: Assure the call is made with the API token properly used in the 'Authorization' header. """ - mocker.patch.object(OktaClient, 'initial_setup') client = OktaClient( base_url='https://test.url', api_token='X', @@ -354,7 +346,6 @@ def test_http_request_oauth_auth(mocker): When: Making an API call with OAuth authentication Then: Assure the call is made with the JWT token properly used in the 'Authorization' header. """ - mocker.patch.object(OktaClient, 'initial_setup') client = OktaClient( base_url='https://test.url', api_token='X', diff --git a/Packs/Okta/Integrations/Okta_v2/Okta_v2.py b/Packs/Okta/Integrations/Okta_v2/Okta_v2.py index a92b84a41afe..d41c71c98dd3 100644 --- a/Packs/Okta/Integrations/Okta_v2/Okta_v2.py +++ b/Packs/Okta/Integrations/Okta_v2/Okta_v2.py @@ -1371,18 +1371,8 @@ def delete_limit_param(url): def main(): try: params = demisto.params() - base_url = params['url'].rstrip('/') - - api_token = params.get("credentials", {}).get("password") or params.get('apitoken') - - if not api_token: - raise ValueError('Missing API token.') - - verify_certificate = not params.get('insecure', False) - proxy = params.get('proxy', False) demisto.debug(f'Command being called is {demisto.command()}') - commands = { 'test-module': module_test, 'okta-unlock-user': unlock_user_command, @@ -1422,19 +1412,18 @@ def main(): } command = demisto.command() - auth_type = AuthType.OAUTH if argToBoolean(params.get('use_oauth', False)) else AuthType.API_TOKEN client = Client( - base_url=base_url, - verify=verify_certificate, + base_url=params['url'].rstrip('/'), + verify=(not params.get('insecure', False)), headers={ 'Accept': 'application/json', 'Content-Type': 'application/json', }, - proxy=proxy, + proxy=params.get('proxy', False), ok_codes=(200, 201, 204), - api_token=api_token, - auth_type=auth_type, + api_token=params.get("credentials", {}).get("password") or params.get('apitoken'), + auth_type=AuthType.OAUTH if argToBoolean(params.get('use_oauth', False)) else AuthType.API_TOKEN, client_id=params.get('client_id'), scopes=OAUTH_TOKEN_SCOPES, private_key=params.get('private_key'), diff --git a/Packs/Okta/Integrations/Okta_v2/Okta_v2.yml b/Packs/Okta/Integrations/Okta_v2/Okta_v2.yml index 25404e4572a5..5f8981cb3fa9 100644 --- a/Packs/Okta/Integrations/Okta_v2/Okta_v2.yml +++ b/Packs/Okta/Integrations/Okta_v2/Okta_v2.yml @@ -37,13 +37,13 @@ configuration: required: false additionalinfo: Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. - display: Private Key - additionalinfo: Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. + additionalinfo: In PEM format. Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. name: private_key type: 14 section: Connect required: false -- display: JWT Encoding Algorithm - additionalinfo: Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. +- display: JWT Signing Algorithm + additionalinfo: Algorithm to sign generated JWT tokens with. Doesn't affect integration's functionality. Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. name: jwt_algorithm type: 15 section: Connect @@ -340,13 +340,13 @@ script: - arguments: - description: "The cursor in which to retrive the results from and on. if the query didn't reach the end of results, the tag can be obtained from the bottom of the grid in the readable output, or in the context path Okta.User.tag." name: after - - description: The maximum number of results to return, the default is 200. + - description: The maximum number of results to return. name: limit default: true defaultValue: '200' - auto: PREDEFINED defaultValue: 'false' - description: Whether to return extended user information. Can be "true" or "false". The default is "false". + description: Whether to return extended user information. name: verbose predefined: - 'true' @@ -1417,16 +1417,16 @@ script: name: okta-create-group outputs: - contextPath: OktaGroup.ID - description: Group ID in Okta,. + description: Group ID in Okta. type: Unknown - contextPath: OktaGroup.Name - description: Group name in Okta,. + description: Group name in Okta. type: Unknown - contextPath: OktaGroup.Description - description: Group description in Okta,. + description: Group description in Okta. type: Unknown - contextPath: OktaGroup.Type - description: Group type in Okta,. + description: Group type in Okta. type: Unknown - arguments: - description: Name of the group to assign to the app. @@ -1485,7 +1485,7 @@ script: type: String - description: Reset OAuth authentication data (authentication process will start from the beginning, and a new token will be generated). name: okta-auth-reset - dockerimage: demisto/crypto:1.0.0.83343 + dockerimage: demisto/crypto:1.0.0.87358 runonce: false script: "" subtype: python3 diff --git a/Packs/Okta/Integrations/Okta_v2/Okta_v2_description.md b/Packs/Okta/Integrations/Okta_v2/Okta_v2_description.md index c9422dd33268..01472d28134e 100644 --- a/Packs/Okta/Integrations/Okta_v2/Okta_v2_description.md +++ b/Packs/Okta/Integrations/Okta_v2/Okta_v2_description.md @@ -2,16 +2,15 @@ Okta API tokens are used to authenticate requests to Okta APIs. ### Prerequisites -1. Sign in to your Okta organization as a user with administrator privileges. -2. In the Admin Console, select **Security** > **API** from the menu and then select the **Tokens** tab. +1. Sign in to your Okta organization as a user **with administrator privileges**. +2. In the Admin Console, select **Security** > **API** from the menu, and then select the **Tokens** tab. 3. Click **Create Token**. 4. Name your token and click **Create Token**. #### Notes -- API tokens have the same permissions as the user who creates them, and if the user permissions change, the API token permissions also change. +- API tokens have the same permissions as the user who creates them, and if the permissions of a user change, so do the permissions of the API token. -For more information, see the '[Create an API token -](https://developer.okta.com/docs/guides/create-an-api-token/main/)' official documentation article. +For more information, see the '[Create an API token](https://developer.okta.com/docs/guides/create-an-api-token/main/)' official documentation article. ## Authentication using OAuth 2.0 Authentication As an alternative to Okta API tokens, you can interact with Okta APIs using scoped OAuth 2.0 access tokens for a number of Okta endpoints. @@ -33,16 +32,22 @@ The following scopes are required for the Okta v2 integration to work properly: ### Prerequisites -1. Generate an API token as described previously. This is required for some backend API calls that are needed to set up OAuth authentication. -2. Sign in to your Okta organization as a user with administrative privileges. -3. In the Admin Console, go to **Applications** > **Applications**. -4. Click **Create App Integration**. -5. Select **API Services** as the sign-in method, and click **Next**. -6. Enter a name for your app integration. -7. On the app configuration page, under the **General** tab and the **Client Credentials** section, select **Public key / Private key** for the **Client authentication** option. -8. Under the newly added **PUBLIC KEYS** section, click the **Add Key** button. -9. In the **Add Public Key** dialog box, click **Generate new key**, and make sure to keep the private key (in PEM format) in somewhere safe. -10. On the app configuration page, under the **Okta API Scopes** tab, make sure that the required scopes mentioned above are granted. - -For more information, see the '[Implement OAuth for Okta -](https://developer.okta.com/docs/guides/implement-oauth-for-okta/main/)' official documentation article. +1. Sign in to Okta Admin Console. +2. In the Admin Console, go to **Applications** > **Applications**. +3. Click **Create App Integration**. +4. Select **API Services** as the sign-in method, and click **Next**. +5. Enter the desired name for the created app (e.g., "Cortex XSOAR"), and click **Save**. +6. In the app configuration page, under the **General** tab and the **Client Credentials** section, select **Public key / Private key** for the **Client authentication** option. +7. Under the newly added **PUBLIC KEYS** section, click **Add Key**. +8. In the **Add Public Key** dialog box, click **Generate new key**. Make sure to copy the generated private key (in PEM format) to somewhere safe, and click **Save**. +9. Under the **General Settings** section: + 1. Next to the **Proof of possession** label, uncheck the **Require Demonstrating Proof of Possession (DPoP) header in token requests** option if it's selected. + 2. Next to the **Grant type** label, make sure the **Client Credentials** option is selected, and that the **Token Exchange** option is not selected. + 3. Click **Save**. +10. Under the **Okta API Scopes** tab, grant the required scopes mentioned above for the app. +11. Under the **Admin roles** tab: + 1. Click **Edit assignments**. + 2. In the dropdown list under "Role", select **Super Administrator**. + 3. Click **Save changes** at the top. + +For more information, see the '[Implement OAuth for Okta](https://developer.okta.com/docs/guides/implement-oauth-for-okta/main/)' official documentation article. diff --git a/Packs/Okta/Integrations/Okta_v2/README.md b/Packs/Okta/Integrations/Okta_v2/README.md index 5f7c4fae6b77..697f528a2893 100644 --- a/Packs/Okta/Integrations/Okta_v2/README.md +++ b/Packs/Okta/Integrations/Okta_v2/README.md @@ -1,23 +1,18 @@ -## Configure Okta v2 on Cortex XSOAR - -### Authentication using API Token -Okta API tokens are used to authenticate requests to Okta APIs. +Integration with Okta's cloud-based identity management service. -#### Prerequisites +## Configure Okta v2 on Cortex XSOAR +### API Token Authentication Prerequisites 1. Sign in to your Okta organization as a user with administrator privileges. -2. In the Admin Console, select **Security > API** from the menu and then select the **Tokens** tab. +2. On the **Admin Console**, select **Security** > **API** from the menu, and then select the **Tokens** tab. 3. Click **Create Token**. 4. Name your token and click **Create Token**. -##### Notes -- API tokens have the same permissions as the user who creates them, and if the user permissions change, the API token permissions also change. +#### Notes +- API tokens have the same permissions as the user who creates them, and if the permissions of a user change, so do the permissions of the API token. For more information, see the '[Create an API token](https://developer.okta.com/docs/guides/create-an-api-token/main/)' official documentation article. -### Authentication using OAuth 2.0 Authentication -As an alternative to Okta API tokens, you can interact with Okta APIs using scoped OAuth 2.0 access tokens for a number of Okta endpoints. -Each access token enables the bearer to perform specific actions on specific Okta endpoints, with that ability controlled by which scopes the access token contains. - +### OAuth 2.0 Authentication Prerequisites #### Required Scopes The following scopes are required for the Okta v2 integration to work properly: - okta.apps.manage @@ -32,21 +27,27 @@ The following scopes are required for the Okta v2 integration to work properly: - okta.users.manage - okta.users.read - -##### Prerequisites -1. Generate an API token as described previously. This is required for some backend API calls that are needed to setup OAuth authentication. -2. Sign in to your Okta organization as a user with administrative privileges. -3. In the Admin Console, go to **Applications** > **Applications**. -4. Click **Create App Integration**. -5. Select **API Services** as the sign-in method, and click **Next**. -6. Enter a name for your app integration. -7. On the app configuration page, under the **General** tab and the **Client Credentials** section, select **Public key / Private key** for the **Client authentication** option. -8. Under the newly added **PUBLIC KEYS** section, click the **Add Key** button. -9. In the **Add Public Key** dialog box, click **Generate new key**, and make sure to keep the private key (in PEM format) in somewhere safe. -10. On the app configuration page, under the **Okta API Scopes** tab, make sure that the required scopes mentioned above are granted. +1. Sign in to Okta Admin Console. +2. In the Admin Console, go to **Applications** > **Applications**. +3. Click **Create App Integration**. +4. Select **API Services** as the sign-in method, and click **Next**. +5. Enter the desired name for the created app (e.g., "Cortex XSOAR"), and click **Save**. +6. In the app configuration page, under the **General** tab and the **Client Credentials** section, select **Public key / Private key** for the **Client authentication** option. +7. Under the newly added **PUBLIC KEYS** section, click **Add Key**. +8. In the **Add Public Key** dialog box, click **Generate new key**. Make sure to copy the generated private key (in PEM format) to somewhere safe, and click **Save**. +9. Under the **General Settings** section: + 1. Next to the **Proof of possession** label, uncheck the **Require Demonstrating Proof of Possession (DPoP) header in token requests** option if it's selected. + 2. Next to the **Grant type** label, make sure the **Client Credentials** option is selected, and that the **Token Exchange** option is not selected. + 3. Click **Save**. +10. Under the **Okta API Scopes** tab, grant the required scopes mentioned above for the app. +11. Under the **Admin roles** tab: + 1. Click **Edit assignments**. + 2. In the dropdown list under "Role", select **Super Administrator**. + 3. Click **Save changes** at the top. For more information, see the '[Implement OAuth for Okta](https://developer.okta.com/docs/guides/implement-oauth-for-okta/main/)' official documentation article. + ### Instance Configuration 1. Navigate to **Settings** > **Integrations** > **Servers & Services**. 2. Search for Okta v2. @@ -58,8 +59,8 @@ For more information, see the '[Implement OAuth for Okta](https://developer.okta | API Token | | False | | Use OAuth 2.0 Authentication | See detailed instructions on the 'Help' tab. | False | | Client ID | Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. | False | - | Private Key | Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. | False | - | JWT Encoding Algorithm | Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. | False | + | Private Key | In PEM format. Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. | False | + | JWT Signing Algorithm | Algorithm to sign generated JWT tokens with. Doesn't affect integration's functionality. Required and used if OAuth 2.0 is used for authentication. See detailed instructions on the 'Help' tab. | False | | Trust any certificate (not secure) | | False | | Use system proxy settings | | False | @@ -749,7 +750,6 @@ Lists users in your organization. | Account.PasswordChanged | Date | Timestamp for when the user's password was last changed. | | Okta.User.tag | String | The location of the next item, used with after param. | - ### okta-create-user *** diff --git a/Packs/Okta/ReleaseNotes/3_2_11.md b/Packs/Okta/ReleaseNotes/3_2_11.md new file mode 100644 index 000000000000..4aace813ebbf --- /dev/null +++ b/Packs/Okta/ReleaseNotes/3_2_11.md @@ -0,0 +1,8 @@ + +#### Integrations + +##### Okta v2 + +- *API Token* field is no longer required when configuring an instance using OAuth authentication. + Since the API token was previously used to set the app with a "Super Administrator" role, this role will be needed to be set manually for newly created apps (see [the documentation](https://xsoar.pan.dev/docs/reference/integrations/okta-v2#oauth-20-authentication-prerequisites) for more information). +- Updated the Docker image to: *demisto/crypto:1.0.0.87358*. diff --git a/Packs/Okta/pack_metadata.json b/Packs/Okta/pack_metadata.json index 41436e4430cd..74bd96b59ff7 100644 --- a/Packs/Okta/pack_metadata.json +++ b/Packs/Okta/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Okta", "description": "Integration with Okta's cloud-based identity management service.", "support": "xsoar", - "currentVersion": "3.2.10", + "currentVersion": "3.2.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 9c886082d4ce7c05a0bdc2715cc381bee696f9ae Mon Sep 17 00:00:00 2001 From: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Date: Sun, 18 Feb 2024 17:25:05 +0200 Subject: [PATCH 007/272] [Xsup 33523] fix for microsoft-365-defender-advanced-hunting (#32976) * reproduce the error * replace split by "|" with regex * update rn * pre commit * update docker --- .../Microsoft365Defender/Microsoft365Defender.py | 2 +- .../Microsoft365Defender/Microsoft365Defender.yml | 8 ++++---- .../Microsoft365Defender/Microsoft365Defender_test.py | 5 +++-- Packs/Microsoft365Defender/ReleaseNotes/4_5_18.md | 6 ++++++ Packs/Microsoft365Defender/pack_metadata.json | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) create mode 100644 Packs/Microsoft365Defender/ReleaseNotes/4_5_18.md diff --git a/Packs/Microsoft365Defender/Integrations/Microsoft365Defender/Microsoft365Defender.py b/Packs/Microsoft365Defender/Integrations/Microsoft365Defender/Microsoft365Defender.py index 656ddb4b08e1..b52f24a7b7a7 100644 --- a/Packs/Microsoft365Defender/Integrations/Microsoft365Defender/Microsoft365Defender.py +++ b/Packs/Microsoft365Defender/Integrations/Microsoft365Defender/Microsoft365Defender.py @@ -532,7 +532,7 @@ def _query_set_limit(query: str, limit: int) -> str: return query # the query has the structure of "section | section | section ..." - query_list = query.split('|') + query_list = re.split(r'(? Date: Sun, 18 Feb 2024 17:53:10 +0200 Subject: [PATCH 008/272] [AlienVault] Add error handling for convert_timestamp_to_iso86 (#32958) --- .../AlienVault_USM_Anywhere.py | 27 ++++++++++--------- .../AlienVault_USM_Anywhere.yml | 2 +- .../AlienVault_USM_Anywhere_test.py | 16 ++++++----- .../ReleaseNotes/1_0_22.md | 6 +++++ .../pack_metadata.json | 2 +- 5 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 Packs/AlienVault_USM_Anywhere/ReleaseNotes/1_0_22.md diff --git a/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere.py b/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere.py index 0e810e939d44..38ac3d9a549a 100644 --- a/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere.py +++ b/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere.py @@ -8,7 +8,6 @@ import dateparser import urllib3 from datetime import datetime -from typing import Dict # Disable insecure warnings urllib3.disable_warnings() @@ -77,7 +76,7 @@ def http_request(method, url_suffix, params=None, headers=None, data=None, **kwa if res.status_code == 401: raise Exception('UnauthorizedError: please validate your credentials.') if res.status_code not in {200}: - raise Exception('Error in API call to Example Integration [{}] - {}'.format(res.status_code, res.reason)) + raise Exception(f'Error in API call to Example Integration [{res.status_code}] - {res.reason}') return res.json() @@ -133,7 +132,7 @@ def get_time_range(time_frame=None, start_time=None, end_time=None): elif time_frame == 'Last 30 Days': start_time = end_time - timedelta(days=30) else: - raise ValueError('Could not parse time frame: {}'.format(time_frame)) + raise ValueError(f'Could not parse time frame: {time_frame}') return date_to_timestamp(start_time), date_to_timestamp(end_time) @@ -150,8 +149,12 @@ def convert_timestamp_to_iso86(timestamp: str, timezone_letter: str = 'Z') -> st """ if not timestamp: return '' - datetime_from_timestamp = dateparser.parse(timestamp, settings={"TO_TIMEZONE": timezone_letter, - "RETURN_AS_TIMEZONE_AWARE": True}) + try: + datetime_from_timestamp = dateparser.parse(str(timestamp), settings={"TO_TIMEZONE": timezone_letter, + "RETURN_AS_TIMEZONE_AWARE": True}) + except Exception as e: + demisto.error(f"Encountered issue parsing {timestamp}. err: {str(e)}") + return '' assert datetime_from_timestamp is not None, f'{timestamp} could not be parsed' time_in_iso86 = datetime_from_timestamp.strftime("%Y-%m-%dT%H:%M:%S.%f") return time_in_iso86[:-3] + timezone_letter @@ -261,7 +264,7 @@ def parse_events(events_data): return events -def dict_value_to_int(target_dict: Dict, key: str): +def dict_value_to_int(target_dict: dict, key: str): """ :param target_dict: A dictionary which has the key param :param key: The key that we need to convert it's value to integer @@ -321,7 +324,7 @@ def get_alarm_command(): # Parse response into context & content entries alarm_details = parse_alarms(response) - return_outputs(tableToMarkdown('Alarm {}'.format(alarm_id), alarm_details), + return_outputs(tableToMarkdown(f'Alarm {alarm_id}', alarm_details), {'AlienVault.Alarm(val.ID && val.ID == obj.ID)': alarm_details}, response) @@ -363,7 +366,7 @@ def search_alarms(start_time=None, end_time=None, status=None, priority=None, sh params = { 'page': 0, 'size': limit, - 'sort': 'timestamp_occured,{}'.format(direction), + 'sort': f'timestamp_occured,{direction}', 'suppressed': show_suppressed } @@ -417,7 +420,7 @@ def search_events(start_time=None, end_time=None, account_name=None, event_name= params = { 'page': 1, 'size': limit, - 'sort': 'timestamp_occured,{}'.format(direction), + 'sort': f'timestamp_occured,{direction}', } if account_name: @@ -447,7 +450,7 @@ def get_events_by_alarm_command(): events = parse_events(alarm['events']) - return_outputs(tableToMarkdown('Events of Alarm {}:'.format(alarm_id), events), + return_outputs(tableToMarkdown(f'Events of Alarm {alarm_id}:', events), {'AlienVault.Event(val.ID && val.ID == obj.ID)': events}, alarm) @@ -503,7 +506,7 @@ def fetch_incidents(): def main(): global AUTH_TOKEN cmd = demisto.command() - LOG('Command being called is {}'.format(cmd)) + LOG(f'Command being called is {cmd}') try: handle_proxy() @@ -522,7 +525,7 @@ def main(): LOG.print_log() raise else: - return_error('An error occurred: {}'.format(str(e))) + return_error(f'An error occurred: {str(e)}') # python2 uses __builtin__ python3 uses builtins diff --git a/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere.yml b/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere.yml index e1a0c913b37b..03e75e57ead5 100644 --- a/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere.yml +++ b/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere.yml @@ -340,7 +340,7 @@ script: - contextPath: AlienVault.Event.Subcategory description: The event subcategory. type: String - dockerimage: demisto/python3:3.10.13.72123 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true runonce: false script: '-' diff --git a/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere_test.py b/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere_test.py index 1d995e66df72..b7db2dd511de 100644 --- a/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere_test.py +++ b/Packs/AlienVault_USM_Anywhere/Integrations/AlienVault_USM_Anywhere/AlienVault_USM_Anywhere_test.py @@ -1,4 +1,3 @@ -import io import json import pytest import demistomock as demisto @@ -10,7 +9,7 @@ def util_load_json(path): - with io.open(path, mode='r', encoding='utf-8') as f: + with open(path, encoding='utf-8') as f: return json.loads(f.read()) @@ -93,24 +92,27 @@ def test_get_time_range(): dt = datetime.now() start, end = get_time_range('Today', None, None) - assert datetime.fromtimestamp(start / 1000).date() == dt.date() and approximate_compare(dt, end) + assert datetime.fromtimestamp(start / 1000).date() == dt.date() + assert approximate_compare(dt, end) dt = datetime.now() # should ignore the start/end time values start, end = get_time_range('Today', 'asfd', 'asdf') - assert datetime.fromtimestamp(start / 1000).date() == dt.date() and approximate_compare(dt, end) + assert datetime.fromtimestamp(start / 1000).date() == dt.date() + assert approximate_compare(dt, end) dt = datetime.now() start, end = get_time_range('Yesterday', None, None) - assert datetime.fromtimestamp(start / 1000).date() == (dt.date() - timedelta(days=1)) and approximate_compare(dt, end) + assert datetime.fromtimestamp(start / 1000).date() == (dt.date() - timedelta(days=1)) + assert approximate_compare(dt, end) start, end = get_time_range('Custom', '2019-12-30T01:02:03Z', '2019-12-30T04:05:06Z') assert ((start, end) == (date_to_timestamp(dateparser.parse('2019-12-30T01:02:03Z')), date_to_timestamp(dateparser.parse('2019-12-30T04:05:06Z')))) start, end = get_time_range('Custom', '2019-12-30T01:02:03Z', None) - assert (start == date_to_timestamp(dateparser.parse('2019-12-30T01:02:03Z')) - and approximate_compare(end, datetime.now())) + assert start == date_to_timestamp(dateparser.parse('2019-12-30T01:02:03Z')) + assert approximate_compare(end, datetime.now()) parsed_regular_alarm = {'ID': 'some_uuid', diff --git a/Packs/AlienVault_USM_Anywhere/ReleaseNotes/1_0_22.md b/Packs/AlienVault_USM_Anywhere/ReleaseNotes/1_0_22.md new file mode 100644 index 000000000000..3a48ebd82fc0 --- /dev/null +++ b/Packs/AlienVault_USM_Anywhere/ReleaseNotes/1_0_22.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### AlienVault USM Anywhere +- Fixed an issue where *alienvault-get-alarm* command failed to convert timestamps to iso86 format. +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/AlienVault_USM_Anywhere/pack_metadata.json b/Packs/AlienVault_USM_Anywhere/pack_metadata.json index 84414f7fa0ad..ea1f86012048 100644 --- a/Packs/AlienVault_USM_Anywhere/pack_metadata.json +++ b/Packs/AlienVault_USM_Anywhere/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AlienVault USM Anywhere", "description": "Searches for and monitors alarms and events from AlienVault USM Anywhere.", "support": "xsoar", - "currentVersion": "1.0.21", + "currentVersion": "1.0.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 2a982b9cc77d858946e67dbff9d38809bb71c9a5 Mon Sep 17 00:00:00 2001 From: Anar Azadaliyev Date: Sun, 18 Feb 2024 17:55:24 +0200 Subject: [PATCH 009/272] fix IdentifyAttachedEmail handle None (#32966) * fix IdentifyAttachedEmail handle None * fix docker * add coverage * Bump pack from version CommonScripts to 1.14.0. --------- Co-authored-by: Content Bot --- Packs/CommonScripts/ReleaseNotes/1_14_0.md | 7 ++ .../IdentifyAttachedEmail.py | 3 + .../IdentifyAttachedEmail.yml | 2 +- .../IdentifyAttachedEmail_test.py | 82 +++++++++++++++++++ Packs/CommonScripts/pack_metadata.json | 2 +- 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 Packs/CommonScripts/ReleaseNotes/1_14_0.md diff --git a/Packs/CommonScripts/ReleaseNotes/1_14_0.md b/Packs/CommonScripts/ReleaseNotes/1_14_0.md new file mode 100644 index 000000000000..ccc3ebcf8813 --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_14_0.md @@ -0,0 +1,7 @@ + +#### Scripts + +##### IdentifyAttachedEmail + +- Fixed an issue where the script was erroring when there were no File entries in the warroom. +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail.py b/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail.py index a47585fae16e..307c6de93ab0 100644 --- a/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail.py +++ b/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail.py @@ -66,6 +66,9 @@ def identify_attached_mail(args): else: entries = demisto.executeCommand('getEntries', {"filter": {"categories": ["attachments"]}}) + if not entries: + return 'no', None + for e in entries: id = is_entry_email(e) if id: diff --git a/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail.yml b/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail.yml index dbb7afd937ce..8f1db8a80336 100644 --- a/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail.yml +++ b/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail.yml @@ -28,4 +28,4 @@ tests: - Process Email - Generic - Test - Incident Starter - Phishing v2 - Test - Incident Starter fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.13.86272 +dockerimage: demisto/python3:3.10.13.87159 diff --git a/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail_test.py b/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail_test.py index df84b466f8db..ece17fa892c4 100644 --- a/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail_test.py +++ b/Packs/CommonScripts/Scripts/IdentifyAttachedEmail/IdentifyAttachedEmail_test.py @@ -166,3 +166,85 @@ def execute_command(command, args): results = identify_attached_mail({}) assert results == ('yes', {'reportedemailentryid': '23@2'}) + + +def test_identify_attached_mail_no_email_found(mocker): + """ + Given + - no email entries in the warroom + - the platform is xsoar saas + + When + - running the script to get the entries + + Then + - no entries to be found + + """ + import CommonServerPython + mocker.patch.object(CommonServerPython, 'get_demisto_version', return_value={ + 'version': '8.2.0', + 'buildNumber': '12345' + }) + + def execute_command(command, args): + if command == 'getEntries' and args == {"filter": {"categories": ["attachments"]}}: + return + else: + pytest.fail() + + mocker.patch.object(demisto, 'executeCommand', side_effect=execute_command) + + results = identify_attached_mail({}) + assert results == ('no', None) + + +def test_list_of_entries_passed_in_xsoar_saas_but_no_file_entries(mocker): + """ + Given + - two entries with ids 23@2 24@2 which are not file entries + - the platform is xsoar saas + + When + - running the script to get the entries + + Then + - expect the getEntriesByIDs to be called + - expect no email entries to be found + + """ + entry_ids = """[\"23@2\",\"24@2\"]""" + import CommonServerPython + mocker.patch.object(CommonServerPython, 'get_demisto_version', return_value={ + 'version': '8.2.0', + 'buildNumber': '12345' + }) + + def execute_command(command, args): + if command == 'getEntriesByIDs' and args.get('entryIDs') == '23@2,24@2': + return [ + { + 'File': 'msg.txt', + 'FileMetadata': { + 'info': 'ASCII text, with CRLF line terminators' + }, + 'ID': '23@2' + }, + { + 'File': 'foo.txt', + 'FileMetadata': { + 'info': 'ASCII text, with CRLF line terminators' + }, + 'ID': '24@2' + } + ] + else: + pytest.fail() + + mocker.patch.object(demisto, 'executeCommand', side_effect=execute_command) + + args = { + 'entryid': entry_ids + } + results = identify_attached_mail(args) + assert results == ('no', None) diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index ef668157d2b1..293d37cc7cee 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.13.40", + "currentVersion": "1.14.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e14e854e6a53eeb88a19d7ead3a053f84a4cdc37 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:22:57 +0200 Subject: [PATCH 010/272] Update `demisto/dxl` 25-40 coverage rate (#32648) * upgrade images * update RN --- Packs/McAfee-MAR/Integrations/McAfee-MAR/McAfee-MAR.yml | 2 +- Packs/McAfee-MAR/ReleaseNotes/1_0_8.md | 6 ++++++ Packs/McAfee-MAR/pack_metadata.json | 2 +- Packs/McAfee_DXL/Integrations/McAfee_DXL/McAfee_DXL.yml | 2 +- Packs/McAfee_DXL/ReleaseNotes/1_0_5.md | 6 ++++++ Packs/McAfee_DXL/pack_metadata.json | 2 +- 6 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 Packs/McAfee-MAR/ReleaseNotes/1_0_8.md create mode 100644 Packs/McAfee_DXL/ReleaseNotes/1_0_5.md diff --git a/Packs/McAfee-MAR/Integrations/McAfee-MAR/McAfee-MAR.yml b/Packs/McAfee-MAR/Integrations/McAfee-MAR/McAfee-MAR.yml index aec95a02a0db..0a3cc52b00a6 100644 --- a/Packs/McAfee-MAR/Integrations/McAfee-MAR/McAfee-MAR.yml +++ b/Packs/McAfee-MAR/Integrations/McAfee-MAR/McAfee-MAR.yml @@ -496,7 +496,7 @@ script: - contextPath: MAR.HostInfo.Os description: Host operation system description: Gets host information from McAfee Active Response - dockerimage: demisto/dxl:1.0.0.63890 + dockerimage: demisto/dxl:1.0.0.86273 fromversion: 5.0.0 tests: - No tests (auto formatted) diff --git a/Packs/McAfee-MAR/ReleaseNotes/1_0_8.md b/Packs/McAfee-MAR/ReleaseNotes/1_0_8.md new file mode 100644 index 000000000000..2d076089a968 --- /dev/null +++ b/Packs/McAfee-MAR/ReleaseNotes/1_0_8.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### McAfee Active Response + +- Updated the Docker image to: *demisto/dxl:1.0.0.86273*. diff --git a/Packs/McAfee-MAR/pack_metadata.json b/Packs/McAfee-MAR/pack_metadata.json index ff17f7b5b06a..f4de82ba9cc9 100644 --- a/Packs/McAfee-MAR/pack_metadata.json +++ b/Packs/McAfee-MAR/pack_metadata.json @@ -2,7 +2,7 @@ "name": "McAfee Active Response", "description": "Connect to MAR using its DXL client", "support": "xsoar", - "currentVersion": "1.0.7", + "currentVersion": "1.0.8", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/McAfee_DXL/Integrations/McAfee_DXL/McAfee_DXL.yml b/Packs/McAfee_DXL/Integrations/McAfee_DXL/McAfee_DXL.yml index e5825f01def4..6634e8b75ae1 100644 --- a/Packs/McAfee_DXL/Integrations/McAfee_DXL/McAfee_DXL.yml +++ b/Packs/McAfee_DXL/Integrations/McAfee_DXL/McAfee_DXL.yml @@ -141,7 +141,7 @@ script: name: topic description: The push hash to the DXL fabric. name: dxl-push-hash - dockerimage: demisto/dxl:1.0.0.35274 + dockerimage: demisto/dxl:1.0.0.86273 runonce: false script: '-' subtype: python3 diff --git a/Packs/McAfee_DXL/ReleaseNotes/1_0_5.md b/Packs/McAfee_DXL/ReleaseNotes/1_0_5.md new file mode 100644 index 000000000000..7932a80fb22a --- /dev/null +++ b/Packs/McAfee_DXL/ReleaseNotes/1_0_5.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### McAfee DXL + +- Updated the Docker image to: *demisto/dxl:1.0.0.86273*. diff --git a/Packs/McAfee_DXL/pack_metadata.json b/Packs/McAfee_DXL/pack_metadata.json index 96608cc156ff..9b111b8faa31 100644 --- a/Packs/McAfee_DXL/pack_metadata.json +++ b/Packs/McAfee_DXL/pack_metadata.json @@ -2,7 +2,7 @@ "name": "McAfee DXL", "description": "McAfee DXL client", "support": "xsoar", - "currentVersion": "1.0.4", + "currentVersion": "1.0.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From d40f35cc5f9215c26ae647e2b871f6f9c0cfe299 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:23:11 +0200 Subject: [PATCH 011/272] Update `demisto/googleapi-python3` 0-10 coverage rate (#32646) * upgrade images * update RN --- .../Integrations/GoogleCloudCompute/GoogleCloudCompute.yml | 2 +- Packs/GoogleCloudCompute/ReleaseNotes/1_1_8.md | 6 ++++++ Packs/GoogleCloudCompute/pack_metadata.json | 2 +- .../GoogleResourceManager/GoogleResourceManager.yml | 2 +- Packs/GoogleResourceManager/ReleaseNotes/1_0_5.md | 6 ++++++ Packs/GoogleResourceManager/pack_metadata.json | 2 +- Packs/GoogleVault/Integrations/GoogleVault/GoogleVault.yml | 2 +- Packs/GoogleVault/ReleaseNotes/1_0_12.md | 6 ++++++ Packs/GoogleVault/pack_metadata.json | 2 +- 9 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 Packs/GoogleCloudCompute/ReleaseNotes/1_1_8.md create mode 100644 Packs/GoogleResourceManager/ReleaseNotes/1_0_5.md create mode 100644 Packs/GoogleVault/ReleaseNotes/1_0_12.md diff --git a/Packs/GoogleCloudCompute/Integrations/GoogleCloudCompute/GoogleCloudCompute.yml b/Packs/GoogleCloudCompute/Integrations/GoogleCloudCompute/GoogleCloudCompute.yml index 788b82f6b864..242bfe9f2c9b 100644 --- a/Packs/GoogleCloudCompute/Integrations/GoogleCloudCompute/GoogleCloudCompute.yml +++ b/Packs/GoogleCloudCompute/Integrations/GoogleCloudCompute/GoogleCloudCompute.yml @@ -8418,7 +8418,7 @@ script: - contextPath: GoogleCloudCompute.Instances.kind description: '] Type of the resource. Always compute#instance for instances.' type: string - dockerimage: demisto/googleapi-python3:1.0.0.65068 + dockerimage: demisto/googleapi-python3:1.0.0.86653 script: '' subtype: python3 type: python diff --git a/Packs/GoogleCloudCompute/ReleaseNotes/1_1_8.md b/Packs/GoogleCloudCompute/ReleaseNotes/1_1_8.md new file mode 100644 index 000000000000..032ca560c148 --- /dev/null +++ b/Packs/GoogleCloudCompute/ReleaseNotes/1_1_8.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Google Cloud Compute + +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.86653*. diff --git a/Packs/GoogleCloudCompute/pack_metadata.json b/Packs/GoogleCloudCompute/pack_metadata.json index c04c4a974d4f..e3b440eb9a2b 100644 --- a/Packs/GoogleCloudCompute/pack_metadata.json +++ b/Packs/GoogleCloudCompute/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Cloud Compute", "description": "Google Compute Engine delivers virtual machines running in Google's innovative data centers and worldwide fiber network. Compute Engine's tooling and workflow support enable scaling from single instances to global, load-balanced cloud computing.", "support": "xsoar", - "currentVersion": "1.1.7", + "currentVersion": "1.1.8", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GoogleResourceManager/Integrations/GoogleResourceManager/GoogleResourceManager.yml b/Packs/GoogleResourceManager/Integrations/GoogleResourceManager/GoogleResourceManager.yml index dbbe230b69d6..8c19462fa8d9 100644 --- a/Packs/GoogleResourceManager/Integrations/GoogleResourceManager/GoogleResourceManager.yml +++ b/Packs/GoogleResourceManager/Integrations/GoogleResourceManager/GoogleResourceManager.yml @@ -397,7 +397,7 @@ script: - contextPath: GRM.Project.Parent.Type description: Type of the parent resource. type: String - dockerimage: demisto/googleapi-python3:1.0.0.63869 + dockerimage: demisto/googleapi-python3:1.0.0.86653 runonce: false script: '' type: python diff --git a/Packs/GoogleResourceManager/ReleaseNotes/1_0_5.md b/Packs/GoogleResourceManager/ReleaseNotes/1_0_5.md new file mode 100644 index 000000000000..2909de985d9f --- /dev/null +++ b/Packs/GoogleResourceManager/ReleaseNotes/1_0_5.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Google Resource Manager + +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.86653*. diff --git a/Packs/GoogleResourceManager/pack_metadata.json b/Packs/GoogleResourceManager/pack_metadata.json index bfd837000213..04c18d3cc213 100644 --- a/Packs/GoogleResourceManager/pack_metadata.json +++ b/Packs/GoogleResourceManager/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Resource Manager", "description": "Google Cloud Platform Resource Manager", "support": "xsoar", - "currentVersion": "1.0.4", + "currentVersion": "1.0.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GoogleVault/Integrations/GoogleVault/GoogleVault.yml b/Packs/GoogleVault/Integrations/GoogleVault/GoogleVault.yml index f845b7271fe6..e805adba7525 100644 --- a/Packs/GoogleVault/Integrations/GoogleVault/GoogleVault.yml +++ b/Packs/GoogleVault/Integrations/GoogleVault/GoogleVault.yml @@ -540,7 +540,7 @@ script: - contextPath: GoogleVault.Matter.Export.Results.To description: The address the message was sent to type: string - dockerimage: demisto/googleapi-python3:1.0.0.64742 + dockerimage: demisto/googleapi-python3:1.0.0.86653 runonce: false script: '-' subtype: python3 diff --git a/Packs/GoogleVault/ReleaseNotes/1_0_12.md b/Packs/GoogleVault/ReleaseNotes/1_0_12.md new file mode 100644 index 000000000000..24cd57b50f74 --- /dev/null +++ b/Packs/GoogleVault/ReleaseNotes/1_0_12.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Google Vault + +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.86653*. diff --git a/Packs/GoogleVault/pack_metadata.json b/Packs/GoogleVault/pack_metadata.json index d8817f94a023..3d12651f95fa 100644 --- a/Packs/GoogleVault/pack_metadata.json +++ b/Packs/GoogleVault/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Vault", "description": "Archiving and eDiscovery for G Suite.", "support": "xsoar", - "currentVersion": "1.0.11", + "currentVersion": "1.0.12", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 9be11ce0befff7868308a98e98e1b81e47682368 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:23:21 +0200 Subject: [PATCH 012/272] Update `demisto/google-api-py3` 25-40 coverage rate (#32645) * upgrade images * update RN --- .../GoogleCloudFunctions/GoogleCloudFunctions.yml | 2 +- Packs/GoogleCloudFunctions/ReleaseNotes/1_0_27.md | 6 ++++++ Packs/GoogleCloudFunctions/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/GoogleCloudFunctions/ReleaseNotes/1_0_27.md diff --git a/Packs/GoogleCloudFunctions/Integrations/GoogleCloudFunctions/GoogleCloudFunctions.yml b/Packs/GoogleCloudFunctions/Integrations/GoogleCloudFunctions/GoogleCloudFunctions.yml index ece6b7d2d9a8..c9dbde8d83a0 100644 --- a/Packs/GoogleCloudFunctions/Integrations/GoogleCloudFunctions/GoogleCloudFunctions.yml +++ b/Packs/GoogleCloudFunctions/Integrations/GoogleCloudFunctions/GoogleCloudFunctions.yml @@ -114,7 +114,7 @@ script: - contextPath: GoogleCloudFunctions.Execution.error description: Either a system or user-function generated error. Set if the execution was not successful. type: String - dockerimage: demisto/google-api-py3:1.0.0.64100 + dockerimage: demisto/google-api-py3:1.0.0.86674 runonce: false script: '-' type: python diff --git a/Packs/GoogleCloudFunctions/ReleaseNotes/1_0_27.md b/Packs/GoogleCloudFunctions/ReleaseNotes/1_0_27.md new file mode 100644 index 000000000000..75537ce70df0 --- /dev/null +++ b/Packs/GoogleCloudFunctions/ReleaseNotes/1_0_27.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Google Cloud Functions + +- Updated the Docker image to: *demisto/google-api-py3:1.0.0.86674*. diff --git a/Packs/GoogleCloudFunctions/pack_metadata.json b/Packs/GoogleCloudFunctions/pack_metadata.json index 998007334dcc..8f9d5db56712 100644 --- a/Packs/GoogleCloudFunctions/pack_metadata.json +++ b/Packs/GoogleCloudFunctions/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Cloud Functions", "description": "Google Cloud Functions", "support": "xsoar", - "currentVersion": "1.0.26", + "currentVersion": "1.0.27", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 11da3140a014406486bce7fc64bfabb57ce35e94 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:23:40 +0200 Subject: [PATCH 013/272] Update `demisto/bs4-py3` 0-10 coverage rate (#32637) * upgrade images * update RN --- .../SymantecMessagingGateway/SymantecMessagingGateway.yml | 2 +- Packs/Symantec_Messaging_Gateway/ReleaseNotes/1_0_15.md | 6 ++++++ Packs/Symantec_Messaging_Gateway/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/Symantec_Messaging_Gateway/ReleaseNotes/1_0_15.md diff --git a/Packs/Symantec_Messaging_Gateway/Integrations/SymantecMessagingGateway/SymantecMessagingGateway.yml b/Packs/Symantec_Messaging_Gateway/Integrations/SymantecMessagingGateway/SymantecMessagingGateway.yml index ece80fd84de9..eef326247945 100644 --- a/Packs/Symantec_Messaging_Gateway/Integrations/SymantecMessagingGateway/SymantecMessagingGateway.yml +++ b/Packs/Symantec_Messaging_Gateway/Integrations/SymantecMessagingGateway/SymantecMessagingGateway.yml @@ -118,7 +118,7 @@ script: - name: smg-get-blocked-ips arguments: [] description: Returns a list of all blocked IP addresses. - dockerimage: demisto/bs4-py3:1.0.0.48637 + dockerimage: demisto/bs4-py3:1.0.0.86348 fromversion: 5.0.0 tests: - No tests (auto formatted) diff --git a/Packs/Symantec_Messaging_Gateway/ReleaseNotes/1_0_15.md b/Packs/Symantec_Messaging_Gateway/ReleaseNotes/1_0_15.md new file mode 100644 index 000000000000..486607f6f508 --- /dev/null +++ b/Packs/Symantec_Messaging_Gateway/ReleaseNotes/1_0_15.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Symantec Messaging Gateway + +- Updated the Docker image to: *demisto/bs4-py3:1.0.0.86348*. diff --git a/Packs/Symantec_Messaging_Gateway/pack_metadata.json b/Packs/Symantec_Messaging_Gateway/pack_metadata.json index 9b17e9ce741d..448c8a068c45 100644 --- a/Packs/Symantec_Messaging_Gateway/pack_metadata.json +++ b/Packs/Symantec_Messaging_Gateway/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Symantec Messaging Gateway", "description": "Symantec Messaging Gateway protects against spam, malware, and targeted attacks and provides advanced content filtering, data loss prevention, and email encryption.", "support": "xsoar", - "currentVersion": "1.0.14", + "currentVersion": "1.0.15", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 9eddbe465e99abd5e1394f45b34bb9d00e9eb4e4 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:24:00 +0200 Subject: [PATCH 014/272] Update `demisto/netutils` 0-10 coverage rate (#32631) * upgrade images * update RN --- .../Integrations/FeedPublicDNS/FeedPublicDNS.yml | 2 +- Packs/FeedPublicDNS/ReleaseNotes/1_0_15.md | 6 ++++++ Packs/FeedPublicDNS/pack_metadata.json | 2 +- Packs/Nmap/Integrations/Nmap/Nmap.yml | 2 +- Packs/Nmap/ReleaseNotes/1_2_3.md | 6 ++++++ Packs/Nmap/pack_metadata.json | 2 +- 6 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 Packs/FeedPublicDNS/ReleaseNotes/1_0_15.md create mode 100644 Packs/Nmap/ReleaseNotes/1_2_3.md diff --git a/Packs/FeedPublicDNS/Integrations/FeedPublicDNS/FeedPublicDNS.yml b/Packs/FeedPublicDNS/Integrations/FeedPublicDNS/FeedPublicDNS.yml index f00e17e83d9a..5bc4ef84706f 100644 --- a/Packs/FeedPublicDNS/Integrations/FeedPublicDNS/FeedPublicDNS.yml +++ b/Packs/FeedPublicDNS/Integrations/FeedPublicDNS/FeedPublicDNS.yml @@ -96,7 +96,7 @@ script: name: limit description: Gets indicators from the feed. name: public-dns-get-indicators - dockerimage: demisto/netutils:1.0.0.74582 + dockerimage: demisto/netutils:1.0.0.86390 feed: true runonce: false script: '-' diff --git a/Packs/FeedPublicDNS/ReleaseNotes/1_0_15.md b/Packs/FeedPublicDNS/ReleaseNotes/1_0_15.md new file mode 100644 index 000000000000..f825984a3803 --- /dev/null +++ b/Packs/FeedPublicDNS/ReleaseNotes/1_0_15.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Public DNS Feed + +- Updated the Docker image to: *demisto/netutils:1.0.0.86390*. diff --git a/Packs/FeedPublicDNS/pack_metadata.json b/Packs/FeedPublicDNS/pack_metadata.json index 61ca4714b880..aedb00b8f166 100644 --- a/Packs/FeedPublicDNS/pack_metadata.json +++ b/Packs/FeedPublicDNS/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Public DNS Feed", "description": "The Public DNS Feed fetches known IPs associated with public DNS servers from https://public-dns.info/", "support": "xsoar", - "currentVersion": "1.0.14", + "currentVersion": "1.0.15", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Nmap/Integrations/Nmap/Nmap.yml b/Packs/Nmap/Integrations/Nmap/Nmap.yml index bdefe233642a..eec937eda2df 100644 --- a/Packs/Nmap/Integrations/Nmap/Nmap.yml +++ b/Packs/Nmap/Integrations/Nmap/Nmap.yml @@ -57,4 +57,4 @@ script: description: Additional parseable fields from the script output. description: Scan targets with the given parameters execution: true - dockerimage: demisto/netutils:1.0.0.74582 + dockerimage: demisto/netutils:1.0.0.86390 diff --git a/Packs/Nmap/ReleaseNotes/1_2_3.md b/Packs/Nmap/ReleaseNotes/1_2_3.md new file mode 100644 index 000000000000..cc92e2c8685e --- /dev/null +++ b/Packs/Nmap/ReleaseNotes/1_2_3.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### nmap + +- Updated the Docker image to: *demisto/netutils:1.0.0.86390*. diff --git a/Packs/Nmap/pack_metadata.json b/Packs/Nmap/pack_metadata.json index 061fd90c75d8..bd662c815619 100644 --- a/Packs/Nmap/pack_metadata.json +++ b/Packs/Nmap/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Nmap", "description": "Run nmap scans with the given parameters", "support": "xsoar", - "currentVersion": "1.2.2", + "currentVersion": "1.2.3", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 99df807a363c8dc4c758a2a2444ce190e17374bc Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:24:26 +0200 Subject: [PATCH 015/272] Update `demisto/graphql` 0-10 coverage rate (#32625) * upgrade images * update RN --- Packs/GraphQL/Integrations/GraphQL/GraphQL.yml | 2 +- Packs/GraphQL/ReleaseNotes/1_0_18.md | 6 ++++++ Packs/GraphQL/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/GraphQL/ReleaseNotes/1_0_18.md diff --git a/Packs/GraphQL/Integrations/GraphQL/GraphQL.yml b/Packs/GraphQL/Integrations/GraphQL/GraphQL.yml index 498c65246423..4bb0ef70b218 100644 --- a/Packs/GraphQL/Integrations/GraphQL/GraphQL.yml +++ b/Packs/GraphQL/Integrations/GraphQL/GraphQL.yml @@ -84,7 +84,7 @@ script: - 'false' description: Executes a mutation request to the GraphQL server. name: graphql-mutation - dockerimage: demisto/graphql:1.0.0.45620 + dockerimage: demisto/graphql:1.0.0.86378 runonce: false script: '-' subtype: python3 diff --git a/Packs/GraphQL/ReleaseNotes/1_0_18.md b/Packs/GraphQL/ReleaseNotes/1_0_18.md new file mode 100644 index 000000000000..aa5dfdf45449 --- /dev/null +++ b/Packs/GraphQL/ReleaseNotes/1_0_18.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### GraphQL + +- Updated the Docker image to: *demisto/graphql:1.0.0.86378*. diff --git a/Packs/GraphQL/pack_metadata.json b/Packs/GraphQL/pack_metadata.json index 55572e6473ce..4170043f86a2 100644 --- a/Packs/GraphQL/pack_metadata.json +++ b/Packs/GraphQL/pack_metadata.json @@ -2,7 +2,7 @@ "name": "GraphQL", "description": "Generic GraphQL client to interact with any GraphQL server API.", "support": "xsoar", - "currentVersion": "1.0.17", + "currentVersion": "1.0.18", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 8953ba46ceebbad6e4e3c7a9bffc930598c8d8a7 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:24:51 +0200 Subject: [PATCH 016/272] Update `demisto/blueliv` 0-10 coverage rate (#32624) * upgrade images * update RN --- Packs/Blueliv/Integrations/Blueliv/Blueliv.yml | 2 +- Packs/Blueliv/ReleaseNotes/1_0_3.md | 6 ++++++ Packs/Blueliv/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/Blueliv/ReleaseNotes/1_0_3.md diff --git a/Packs/Blueliv/Integrations/Blueliv/Blueliv.yml b/Packs/Blueliv/Integrations/Blueliv/Blueliv.yml index b01d908285a7..c75086c7fd36 100644 --- a/Packs/Blueliv/Integrations/Blueliv/Blueliv.yml +++ b/Packs/Blueliv/Integrations/Blueliv/Blueliv.yml @@ -37,7 +37,7 @@ script: name: blueliv-get-attackingips-feed - description: 'Data related to the number of hacktivism tweets recently created. Blueliv provides two types of feeds: the first one contains the most popular hacktivism hashtags and the second one contains the countries where more number of hacktivism tweets are coming from.' name: blueliv-get-hacktivism-feed - dockerimage: demisto/blueliv:1.0.0.52588 + dockerimage: demisto/blueliv:1.0.0.76921 runonce: false script: '' type: python diff --git a/Packs/Blueliv/ReleaseNotes/1_0_3.md b/Packs/Blueliv/ReleaseNotes/1_0_3.md new file mode 100644 index 000000000000..b79460975a3f --- /dev/null +++ b/Packs/Blueliv/ReleaseNotes/1_0_3.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Blueliv (Beta) + +- Updated the Docker image to: *demisto/blueliv:1.0.0.76921*. diff --git a/Packs/Blueliv/pack_metadata.json b/Packs/Blueliv/pack_metadata.json index eeda387fb835..69cf2e10ef17 100644 --- a/Packs/Blueliv/pack_metadata.json +++ b/Packs/Blueliv/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Blueliv (Beta)", "description": "Blueliv reduces risk through actionable, dynamic and targeted threat intelligence, trusted by your organization.", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "1.0.3", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 7815b6f6a0678e590ea68fe01e1228bb1f4a6f86 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:27:37 +0200 Subject: [PATCH 017/272] Update `demisto/taxii` 10-25 coverage rate (#32604) * upgrade images * update RN * Bump pack from version FeedAlienVault to 1.1.31. --------- Co-authored-by: Content Bot --- .../FeedAlienVaultOTXTaxii/FeedAlienVaultOTXTaxii.yml | 2 +- Packs/FeedAlienVault/ReleaseNotes/1_1_31.md | 6 ++++++ Packs/FeedAlienVault/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/FeedAlienVault/ReleaseNotes/1_1_31.md diff --git a/Packs/FeedAlienVault/Integrations/FeedAlienVaultOTXTaxii/FeedAlienVaultOTXTaxii.yml b/Packs/FeedAlienVault/Integrations/FeedAlienVaultOTXTaxii/FeedAlienVaultOTXTaxii.yml index 6baeefd08e73..d9c3da1bb49d 100644 --- a/Packs/FeedAlienVault/Integrations/FeedAlienVaultOTXTaxii/FeedAlienVaultOTXTaxii.yml +++ b/Packs/FeedAlienVault/Integrations/FeedAlienVaultOTXTaxii/FeedAlienVaultOTXTaxii.yml @@ -120,7 +120,7 @@ script: name: begin_date description: Gets the indicators from AlienVault OTX. name: alienvaultotx-get-indicators - dockerimage: demisto/taxii:1.0.0.43208 + dockerimage: demisto/taxii:1.0.0.86676 feed: true runonce: false script: '-' diff --git a/Packs/FeedAlienVault/ReleaseNotes/1_1_31.md b/Packs/FeedAlienVault/ReleaseNotes/1_1_31.md new file mode 100644 index 000000000000..9154e3946b6f --- /dev/null +++ b/Packs/FeedAlienVault/ReleaseNotes/1_1_31.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### AlienVault OTX TAXII Feed + +- Updated the Docker image to: *demisto/taxii:1.0.0.86676*. diff --git a/Packs/FeedAlienVault/pack_metadata.json b/Packs/FeedAlienVault/pack_metadata.json index ef1e1c59ed35..4ec738bc5864 100644 --- a/Packs/FeedAlienVault/pack_metadata.json +++ b/Packs/FeedAlienVault/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AlienVault Feed", "description": "Indicators feed from AlienVault", "support": "xsoar", - "currentVersion": "1.1.30", + "currentVersion": "1.1.31", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 123f8db89c6e9b6b34361aafdf09748cd7df142c Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:28:04 +0200 Subject: [PATCH 018/272] Update `demisto/dnstwist` '0-10' coverage rate (#32582) * upgrade images * updateRN --- Packs/dnstwist/Integrations/dnstwist/dnstwist.yml | 2 +- Packs/dnstwist/ReleaseNotes/1_1_13.md | 6 ++++++ Packs/dnstwist/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/dnstwist/ReleaseNotes/1_1_13.md diff --git a/Packs/dnstwist/Integrations/dnstwist/dnstwist.yml b/Packs/dnstwist/Integrations/dnstwist/dnstwist.yml index e966a3133124..aea1ed94185f 100644 --- a/Packs/dnstwist/Integrations/dnstwist/dnstwist.yml +++ b/Packs/dnstwist/Integrations/dnstwist/dnstwist.yml @@ -44,7 +44,7 @@ script: - contextPath: dnstwist.Domain.Domains.WhoisCreated description: Whois created for domain name variations. type: string - dockerimage: demisto/dnstwist:1.0.0.46433 + dockerimage: demisto/dnstwist:1.0.0.86365 runonce: false script: '-' type: python diff --git a/Packs/dnstwist/ReleaseNotes/1_1_13.md b/Packs/dnstwist/ReleaseNotes/1_1_13.md new file mode 100644 index 000000000000..cdda90ae3f00 --- /dev/null +++ b/Packs/dnstwist/ReleaseNotes/1_1_13.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### dnstwist + +- Updated the Docker image to: *demisto/dnstwist:1.0.0.86365*. diff --git a/Packs/dnstwist/pack_metadata.json b/Packs/dnstwist/pack_metadata.json index a12d4d24839d..86b159e85e62 100644 --- a/Packs/dnstwist/pack_metadata.json +++ b/Packs/dnstwist/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Dnstwist", "description": "Use the DNSTwist integration to detect typosquatting, phishing, and corporate espionage.", "support": "xsoar", - "currentVersion": "1.1.12", + "currentVersion": "1.1.13", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From f30ac1443a0269a50ff2eb69179694b067dede96 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:29:05 +0200 Subject: [PATCH 019/272] Update `demisto/fastapi` 0-10 coverage rate (#32571) * upgrade images * update RN * Bump pack from version AlibabaActionTrail to 1.0.24. --------- Co-authored-by: Content Bot --- .../AlibabaActionTrailEventCollector.yml | 2 +- Packs/AlibabaActionTrail/ReleaseNotes/1_0_24.md | 6 ++++++ Packs/AlibabaActionTrail/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/AlibabaActionTrail/ReleaseNotes/1_0_24.md diff --git a/Packs/AlibabaActionTrail/Integrations/AlibabaActionTrailEventCollector/AlibabaActionTrailEventCollector.yml b/Packs/AlibabaActionTrail/Integrations/AlibabaActionTrailEventCollector/AlibabaActionTrailEventCollector.yml index 913bce155274..f257ec20355c 100644 --- a/Packs/AlibabaActionTrail/Integrations/AlibabaActionTrailEventCollector/AlibabaActionTrailEventCollector.yml +++ b/Packs/AlibabaActionTrail/Integrations/AlibabaActionTrailEventCollector/AlibabaActionTrailEventCollector.yml @@ -81,7 +81,7 @@ script: - "True" - "False" required: true - dockerimage: demisto/fastapi:1.0.0.36992 + dockerimage: demisto/fastapi:1.0.0.86524 isfetchevents: true subtype: python3 marketplaces: diff --git a/Packs/AlibabaActionTrail/ReleaseNotes/1_0_24.md b/Packs/AlibabaActionTrail/ReleaseNotes/1_0_24.md new file mode 100644 index 000000000000..39a21e38487f --- /dev/null +++ b/Packs/AlibabaActionTrail/ReleaseNotes/1_0_24.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Alibaba Action Trail Event Collector + +- Updated the Docker image to: *demisto/fastapi:1.0.0.86524*. diff --git a/Packs/AlibabaActionTrail/pack_metadata.json b/Packs/AlibabaActionTrail/pack_metadata.json index 24f2b0f0e8c9..a2903ddc57b3 100644 --- a/Packs/AlibabaActionTrail/pack_metadata.json +++ b/Packs/AlibabaActionTrail/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Alibaba Action Trail", "description": "An Integration Pack to fetch Alibaba action trail events.", "support": "xsoar", - "currentVersion": "1.0.23", + "currentVersion": "1.0.24", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From a46e2317a90de3d194e3051619f830811d6462a2 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:29:42 +0200 Subject: [PATCH 020/272] Upgrade `demisto/boto3py3` items 0-10 coverage rate (#32565) * upgrade images * update RN * update docker * upgrade docker * update AWSWAF --- .../Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml | 2 +- Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md | 6 ++++++ Packs/AWS-CloudWatchLogs/pack_metadata.json | 2 +- .../AWS-NetworkFirewall/AWS-NetworkFirewall.yml | 2 +- Packs/AWS-NetworkFirewall/ReleaseNotes/1_0_5.md | 6 ++++++ Packs/AWS-NetworkFirewall/pack_metadata.json | 2 +- .../AWS_DynamoDB/Integrations/AWS_DynamoDB/AWS_DynamoDB.yml | 2 +- Packs/AWS_DynamoDB/ReleaseNotes/1_0_32.md | 6 ++++++ Packs/AWS_DynamoDB/pack_metadata.json | 2 +- Packs/AWS_WAF/Integrations/AWSWAF/AWSWAF.yml | 2 +- Packs/AWS_WAF/ReleaseNotes/1_0_5.md | 6 ++++++ Packs/AWS_WAF/pack_metadata.json | 2 +- 12 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md create mode 100644 Packs/AWS-NetworkFirewall/ReleaseNotes/1_0_5.md create mode 100644 Packs/AWS_DynamoDB/ReleaseNotes/1_0_32.md create mode 100644 Packs/AWS_WAF/ReleaseNotes/1_0_5.md diff --git a/Packs/AWS-CloudWatchLogs/Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml b/Packs/AWS-CloudWatchLogs/Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml index ec96f2a7f08a..688073e08848 100644 --- a/Packs/AWS-CloudWatchLogs/Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml +++ b/Packs/AWS-CloudWatchLogs/Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml @@ -447,7 +447,7 @@ script: description: The name of the log group. type: string description: Lists the specified metric filters. You can list all the metric filters or filter the results by log name, prefix, metric name, or metric namespace. - dockerimage: demisto/boto3py3:1.0.0.52713 + dockerimage: demisto/boto3py3:1.0.0.87655 tests: - No Tests fromversion: 5.0.0 diff --git a/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md b/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md new file mode 100644 index 000000000000..9078c2c905c1 --- /dev/null +++ b/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### AWS - CloudWatchLogs + +- Updated the Docker image to: *demisto/boto3py3:1.0.0.87655*. diff --git a/Packs/AWS-CloudWatchLogs/pack_metadata.json b/Packs/AWS-CloudWatchLogs/pack_metadata.json index 5a44101bb0a2..ac7edd3c9b04 100644 --- a/Packs/AWS-CloudWatchLogs/pack_metadata.json +++ b/Packs/AWS-CloudWatchLogs/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - CloudWatchLogs", "description": "Amazon Web Services CloudWatch Logs (logs).", "support": "xsoar", - "currentVersion": "1.2.18", + "currentVersion": "1.2.19", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AWS-NetworkFirewall/Integrations/AWS-NetworkFirewall/AWS-NetworkFirewall.yml b/Packs/AWS-NetworkFirewall/Integrations/AWS-NetworkFirewall/AWS-NetworkFirewall.yml index 9dd72d74fab6..4c365ed165ef 100755 --- a/Packs/AWS-NetworkFirewall/Integrations/AWS-NetworkFirewall/AWS-NetworkFirewall.yml +++ b/Packs/AWS-NetworkFirewall/Integrations/AWS-NetworkFirewall/AWS-NetworkFirewall.yml @@ -1512,7 +1512,7 @@ script: - contextPath: AWS-NetworkFirewall.SubnetChangeProtection description: A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE. type: Unknown - dockerimage: demisto/boto3py3:1.0.0.41082 + dockerimage: demisto/boto3py3:1.0.0.87655 runonce: false script: '-' subtype: python3 diff --git a/Packs/AWS-NetworkFirewall/ReleaseNotes/1_0_5.md b/Packs/AWS-NetworkFirewall/ReleaseNotes/1_0_5.md new file mode 100644 index 000000000000..0b9f87dc8ebb --- /dev/null +++ b/Packs/AWS-NetworkFirewall/ReleaseNotes/1_0_5.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### AWS Network Firewall + +- Updated the Docker image to: *demisto/boto3py3:1.0.0.87655*. diff --git a/Packs/AWS-NetworkFirewall/pack_metadata.json b/Packs/AWS-NetworkFirewall/pack_metadata.json index fbf61ab80e13..68716b84325e 100644 --- a/Packs/AWS-NetworkFirewall/pack_metadata.json +++ b/Packs/AWS-NetworkFirewall/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - Network Firewall", "description": "Amazon Web Services Network Firewall", "support": "xsoar", - "currentVersion": "1.0.4", + "currentVersion": "1.0.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AWS_DynamoDB/Integrations/AWS_DynamoDB/AWS_DynamoDB.yml b/Packs/AWS_DynamoDB/Integrations/AWS_DynamoDB/AWS_DynamoDB.yml index 171cc8150f60..a788462d90be 100644 --- a/Packs/AWS_DynamoDB/Integrations/AWS_DynamoDB/AWS_DynamoDB.yml +++ b/Packs/AWS_DynamoDB/Integrations/AWS_DynamoDB/AWS_DynamoDB.yml @@ -2989,7 +2989,7 @@ script: description: The name of the TTL attribute used to store the expiration time for items in the table. - contextPath: AWS-DynamoDB.TimeToLiveSpecification description: Represents the output of an UpdateTimeToLive operation. - dockerimage: demisto/boto3py3:1.0.0.41926 + dockerimage: demisto/boto3py3:1.0.0.87655 script: '' subtype: python3 type: python diff --git a/Packs/AWS_DynamoDB/ReleaseNotes/1_0_32.md b/Packs/AWS_DynamoDB/ReleaseNotes/1_0_32.md new file mode 100644 index 000000000000..4f053df45092 --- /dev/null +++ b/Packs/AWS_DynamoDB/ReleaseNotes/1_0_32.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Amazon DynamoDB + +- Updated the Docker image to: *demisto/boto3py3:1.0.0.87655*. diff --git a/Packs/AWS_DynamoDB/pack_metadata.json b/Packs/AWS_DynamoDB/pack_metadata.json index 3eeacd1d9d23..31e515f5d478 100644 --- a/Packs/AWS_DynamoDB/pack_metadata.json +++ b/Packs/AWS_DynamoDB/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Amazon DynamoDB", "description": "Amazon DynamoDB Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. DynamoDB lets you offload the administrative burdens of operating and scaling a distributed database, so that you don't have to worry about hardware provisioning, setup and configuration, replication, software patching, or cluster scaling. With DynamoDB, you can create database tables that can store and retrieve any amount of data, and serve any level of request traffic. You can scale up or scale down your tables' throughput capacity without downtime or performance degradation, and use the AWS Management Console to monitor resource utilization and performance metrics. DynamoDB automatically spreads the data and traffic for your tables over a sufficient number of servers to handle your throughput and storage requirements, while maintaining consistent and fast performance. All of your data is stored on solid state disks (SSDs) and automatically replicated across multiple Availability Zones in an AWS region, providing built-in high availability and data durability. ", "support": "xsoar", - "currentVersion": "1.0.31", + "currentVersion": "1.0.32", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AWS_WAF/Integrations/AWSWAF/AWSWAF.yml b/Packs/AWS_WAF/Integrations/AWSWAF/AWSWAF.yml index 09312563e557..35b967335714 100644 --- a/Packs/AWS_WAF/Integrations/AWSWAF/AWSWAF.yml +++ b/Packs/AWS_WAF/Integrations/AWSWAF/AWSWAF.yml @@ -1412,7 +1412,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/boto3py3:1.0.0.83962 + dockerimage: demisto/boto3py3:1.0.0.87902 fromversion: 6.5.0 tests: - No tests (auto formatted) diff --git a/Packs/AWS_WAF/ReleaseNotes/1_0_5.md b/Packs/AWS_WAF/ReleaseNotes/1_0_5.md new file mode 100644 index 000000000000..ffb77bbe894e --- /dev/null +++ b/Packs/AWS_WAF/ReleaseNotes/1_0_5.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### AWS-WAF + +- Updated the Docker image to: *demisto/boto3py3:1.0.0.87902*. diff --git a/Packs/AWS_WAF/pack_metadata.json b/Packs/AWS_WAF/pack_metadata.json index b1622a240d31..85f5f0eb4b83 100644 --- a/Packs/AWS_WAF/pack_metadata.json +++ b/Packs/AWS_WAF/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS WAF", "description": "Amazon Web Services Web Application Firewall (WAF)", "support": "xsoar", - "currentVersion": "1.0.4", + "currentVersion": "1.0.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 3588960c74e7fcf866be95202bbade7d1fead1c6 Mon Sep 17 00:00:00 2001 From: Danny Fried Date: Mon, 19 Feb 2024 08:08:28 +0200 Subject: [PATCH 021/272] Awssns listener (#31633) * init commit * Adding missing files, * Remove unnecessary imports * Adding test playbook. Removing redundant fields from yml conf * Adding the TPB to the yml test * Ignoring secret Deleting redundant file * Fix validations issues * Edit readme files. * flake8 error * Adding image * Remove redundant import * Remove redundant file. Fix image name. * Apply suggestions from code review tech doc review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Fix wrong descriptions. * Fix description in yml and README. Fix TestPlaybook * Add instance_names to TPB * Adding store sample logic * update docker version. * Add a unique endpoint instead of the server builtin endpoint * Adding validation to messages * testing long running port * with comments * adding comments * working * Trying to validate the request * Added proxy and verify to call * Removed redundant log writes. Added validation for version2 * Added integration username and password specific verification * bump docker version * Added additional info to username command * updated the README * Logs refactoring * Specified a version in README * remove TODO * README description and yml changes. * Code review changes * Added support for baseclient Added CSP implementation of handle proxy for long runnning integrations * Code review changes * Split long functions * Extracting server config * RN for CSP * Fix READMS. bump docker version. * ignoring false positive secrets * changes ep on tbp * ignore AWS-SNS_Listener TPB * after merge from master * Add unit tests * ignore false positive secret * fix pragma no cover annotation. Bump Base version * ignore demitso.error print from test. --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- Packs/AWS-SNS-Listener/.pack-ignore | 2 + Packs/AWS-SNS-Listener/.secrets-ignore | 3 + .../AWSSNSListener/AWSSNSListener.py | 317 ++++++++++++++ .../AWSSNSListener/AWSSNSListener.yml | 73 ++++ .../AWSSNSListener_description.md | 32 ++ .../AWSSNSListener/AWSSNSListener_image.png | Bin 0 -> 4986 bytes .../AWSSNSListener/AWSSNSListener_test.py | 113 +++++ .../Integrations/AWSSNSListener/README.md | 27 ++ Packs/AWS-SNS-Listener/README.md | 6 + .../TestPlaybooks/AWS_SNS_Listener_-_Test.yml | 385 ++++++++++++++++++ Packs/AWS-SNS-Listener/pack_metadata.json | 22 + Packs/Base/ReleaseNotes/1_33_32.md | 6 + .../CommonServerPython/CommonServerPython.py | 36 ++ Packs/Base/pack_metadata.json | 2 +- Tests/conf.json | 8 +- 15 files changed, 1030 insertions(+), 2 deletions(-) create mode 100644 Packs/AWS-SNS-Listener/.pack-ignore create mode 100644 Packs/AWS-SNS-Listener/.secrets-ignore create mode 100644 Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener.py create mode 100644 Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener.yml create mode 100644 Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_description.md create mode 100644 Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_image.png create mode 100644 Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_test.py create mode 100644 Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/README.md create mode 100644 Packs/AWS-SNS-Listener/README.md create mode 100644 Packs/AWS-SNS-Listener/TestPlaybooks/AWS_SNS_Listener_-_Test.yml create mode 100644 Packs/AWS-SNS-Listener/pack_metadata.json create mode 100644 Packs/Base/ReleaseNotes/1_33_32.md diff --git a/Packs/AWS-SNS-Listener/.pack-ignore b/Packs/AWS-SNS-Listener/.pack-ignore new file mode 100644 index 000000000000..b0151bdf4b20 --- /dev/null +++ b/Packs/AWS-SNS-Listener/.pack-ignore @@ -0,0 +1,2 @@ +[file:AWSSNSListener.yml] +ignore=BA124 \ No newline at end of file diff --git a/Packs/AWS-SNS-Listener/.secrets-ignore b/Packs/AWS-SNS-Listener/.secrets-ignore new file mode 100644 index 000000000000..1a0f000daf66 --- /dev/null +++ b/Packs/AWS-SNS-Listener/.secrets-ignore @@ -0,0 +1,3 @@ +https://sns.eu-central-1.amazonaws.com +https://user:pass@ext-myxsoar-address/xsoar/instance/execute/My-AWS-SNS-Listener/sns_ep +https://link.pem \ No newline at end of file diff --git a/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener.py b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener.py new file mode 100644 index 000000000000..5471d3105487 --- /dev/null +++ b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener.py @@ -0,0 +1,317 @@ +from CommonServerPython import * # noqa: F401 +from CommonServerUserPython import * +from tempfile import NamedTemporaryFile +from traceback import format_exc +from collections import deque +import uvicorn +from secrets import compare_digest +from fastapi import Depends, FastAPI, Request, Response, status +from fastapi.security import HTTPBasic, HTTPBasicCredentials +from fastapi.security.api_key import APIKeyHeader +from fastapi.openapi.models import APIKey +import base64 +from M2Crypto import X509 + + +PARAMS: dict = demisto.params() +sample_events_to_store = deque(maxlen=20) # type: ignore[var-annotated] + +app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None) +basic_auth = HTTPBasic(auto_error=False) +token_auth = APIKeyHeader(auto_error=False, name='Authorization') + + +PROXIES, USE_SSL = handle_proxy_for_long_running() + + +class AWS_SNS_CLIENT(BaseClient): # pragma: no cover + def __init__(self, base_url=None): + if PROXIES: + self.proxies = PROXIES + elif PARAMS.get('proxy'): + self.proxies = handle_proxy() + headers = {'Accept': 'application/json'} + super().__init__(base_url=base_url, proxy=bool(PROXIES), verify=USE_SSL, headers=headers) + + def get(self, full_url, resp_type='json'): + return self._http_request(method='GET', full_url=full_url, proxies=PROXIES, resp_type=resp_type) + + +client = AWS_SNS_CLIENT() + + +class ServerConfig(): # pragma: no cover + def __init__(self, certificate_path, private_key_path, log_config, ssl_args): + self.certificate_path = certificate_path + self.private_key_path = private_key_path + self.log_config = log_config + self.ssl_args = ssl_args + + +def is_valid_sns_message(sns_payload): + """ + Validates an incoming Amazon Simple Notification Service (SNS) message. + + Args: + sns_payload (dict): The SNS payload containing relevant fields. + + Returns: + bool: True if the message is valid, False otherwise. + """ + # taken from https://github.com/boto/boto3/issues/2508 + demisto.debug('In is_valid_sns_message') + # Can only be one of these types. + if sns_payload["Type"] not in ["SubscriptionConfirmation", "Notification", "UnsubscribeConfirmation"]: + demisto.error('Not a valid SNS message') + return False + + # Amazon SNS currently supports signature version 1 or 2. + if sns_payload.get("SignatureVersion") not in ["1", "2"]: + demisto.error('Not using the supported AWS-SNS SignatureVersion 1 or 2') + return False + demisto.debug(f'Handling Signature Version: {sns_payload.get("SignatureVersion")}') + # Fields for a standard notification. + fields = ["Message", "MessageId", "Subject", "Timestamp", "TopicArn", "Type"] + + # Determine the required fields based on message type + if sns_payload["Type"] in ["SubscriptionConfirmation", "UnsubscribeConfirmation"]: + fields = ["Message", "MessageId", "SubscribeURL", "Timestamp", "Token", "TopicArn", "Type"] + + # Build the string to be signed. + string_to_sign = "" + for field in fields: + string_to_sign += field + "\n" + sns_payload[field] + "\n" + + # Verify the signature + decoded_signature = base64.b64decode(sns_payload["Signature"]) + try: + response = client.get(full_url=sns_payload["SigningCertURL"], resp_type='response') + response.raise_for_status() + certificate = X509.load_cert_string(response.text) + except Exception as e: + demisto.error(f'Exception validating sign cert url: {e}') + return False + + public_key = certificate.get_pubkey() + # Verify the signature based on SignatureVersion + if sns_payload["SignatureVersion"] == "1": + public_key.reset_context(md="sha1") + else: # version2 + public_key.reset_context(md="sha256") + + public_key.verify_init() + public_key.verify_update(string_to_sign.encode()) + verification_result = public_key.verify_final(decoded_signature) + + if verification_result != 1: + demisto.error('Signature verification failed.') + return False + + demisto.debug('Signature verification succeeded.') + return True + + +def is_valid_integration_credentials(credentials, request_headers, token): + credentials_param = PARAMS.get('credentials') + auth_failed = False + header_name = None + if credentials_param and (username := credentials_param.get('identifier')): + password = credentials_param.get('password', '') + if username.startswith('_header'): + header_name = username.split(':')[1] + token_auth.model.name = header_name + if not token or not compare_digest(token, password): + auth_failed = True + elif (not credentials) or (not (compare_digest(credentials.username, username) + and compare_digest(credentials.password, password))): + auth_failed = True + if auth_failed: + secret_header = (header_name or 'Authorization').lower() + if secret_header in request_headers: + request_headers[secret_header] = '***' + demisto.debug(f'Authorization failed - request headers {request_headers}') + if auth_failed: # auth failed not valid credentials + return False, header_name + else: + return True, header_name + + +def handle_subscription_confirmation(subscribe_url) -> Response: # pragma: no cover + demisto.debug('SubscriptionConfirmation request') + try: + return client.get(full_url=subscribe_url) + except Exception as e: + demisto.error(f'Failed handling SubscriptionConfirmation: {e}') + return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + content='Failed handling SubscriptionConfirmation') + + +def handle_notification(payload, raw_json): + message = payload['Message'] + demisto.debug(f'Notification request msg: {message}') + return { + 'name': payload['Subject'], + 'labels': [], + 'rawJSON': raw_json, + 'occurred': payload['Timestamp'], + 'details': f'ExternalID:{payload["MessageId"]} TopicArn:{payload["TopicArn"]} Message:{message}', + 'type': 'AWS-SNS Notification' + } + + +def store_samples(incident): # pragma: no cover + try: + sample_events_to_store.append(incident) + integration_context = get_integration_context() + sample_events = deque(json.loads(integration_context.get('sample_events', '[]')), maxlen=20) + sample_events += sample_events_to_store + integration_context['sample_events'] = list(sample_events) + set_to_integration_context_with_retries(integration_context) + except Exception as e: + demisto.error(f'Failed storing sample events - {e}') + + +@app.post(f'/{PARAMS.get("endpoint","")}') +async def handle_post(request: Request, + credentials: HTTPBasicCredentials = Depends(basic_auth), + token: APIKey = Depends(token_auth)): # pragma: no cover + """ + Handles incoming AWS-SNS POST requests. + Supports SubscriptionConfirmation, Notification and UnsubscribeConfirmation. + + Args: + request (Request): The incoming HTTP request. + credentials (HTTPBasicCredentials): Basic authentication credentials. + token (APIKey): API key for authentication. + + Returns: + Union[Response, str]: Response data or error message. + """ + data = '' + request_headers = dict(request.headers) + is_valid_credentials = False + try: + is_valid_credentials, header_name = is_valid_integration_credentials(credentials, request_headers, token) + except Exception as e: + demisto.error(f'Error handling auth failure: {e}') + if not is_valid_credentials: + return Response(status_code=status.HTTP_401_UNAUTHORIZED, content='Authorization failed.') + + secret_header = (header_name or 'Authorization').lower() + request_headers.pop(secret_header, None) + + try: + type = request_headers['x-amz-sns-message-type'] + payload = await request.json() + raw_json = json.dumps(payload) + except Exception as e: + demisto.error(f'Error in request parsing: {e}') + return Response(status_code=status.HTTP_400_BAD_REQUEST, content='Failed parsing request.') + if not is_valid_sns_message(payload): + return 'Validation of SNS message failed.' + + if type == 'SubscriptionConfirmation': + demisto.debug('SubscriptionConfirmation request') + subscribe_url = payload['SubscribeURL'] + try: + response = handle_subscription_confirmation(subscribe_url=subscribe_url) + response.raise_for_status() + except Exception as e: + demisto.error(f'Failed handling SubscriptionConfirmation: {e}') + return 'Failed handling SubscriptionConfirmation' + demisto.debug(f'Response from subscribe url: {response}') + return response + elif type == 'Notification': + incident = handle_notification(payload, raw_json) + data = demisto.createIncidents(incidents=[incident]) + demisto.debug(f'Created incident: {incident}') + if PARAMS.get('store_samples'): + store_samples(incident) + if not data: + demisto.error('Failed creating incident') + data = 'Failed creating incident' + return data + elif type == 'UnsubscribeConfirmation': + message = payload['Message'] + demisto.debug(f'UnsubscribeConfirmation request msg: {message}') + return f'UnsubscribeConfirmation request msg: {message}' + else: + demisto.error(f'Failed handling AWS SNS request, unknown type: {payload["Type"]}') + return f'Failed handling AWS SNS request, unknown type: {payload["Type"]}' + + +def unlink_certificate(certificate_path, private_key_path): # pragma: no cover + if certificate_path: + os.unlink(certificate_path) + if private_key_path: + os.unlink(private_key_path) + time.sleep(5) + + +def setup_server(): # pragma: no cover + certificate = PARAMS.get('certificate', '') + private_key = PARAMS.get('key', '') + + certificate_path = '' + private_key_path = '' + ssl_args = {} + if certificate and private_key: + certificate_file = NamedTemporaryFile(delete=False) + certificate_path = certificate_file.name + certificate_file.write(bytes(certificate, 'utf-8')) + certificate_file.close() + ssl_args['ssl_certfile'] = certificate_path + + private_key_file = NamedTemporaryFile(delete=False) + private_key_path = private_key_file.name + private_key_file.write(bytes(private_key, 'utf-8')) + private_key_file.close() + ssl_args['ssl_keyfile'] = private_key_path + + demisto.debug('Starting HTTPS Server') + else: + demisto.debug('Starting HTTP Server') + + integration_logger = IntegrationLogger() + integration_logger.buffering = False + log_config = dict(uvicorn.config.LOGGING_CONFIG) + log_config['handlers']['default']['stream'] = integration_logger + log_config['handlers']['access']['stream'] = integration_logger + return ServerConfig(log_config=log_config, ssl_args=ssl_args, + certificate_path=certificate_path, private_key_path=private_key_path) + + +''' MAIN FUNCTION ''' + + +def main(): # pragma: no cover + demisto.debug(f'Command being called is {demisto.command()}') + try: + try: + port = PARAMS.get('longRunningPort') + except ValueError as e: + raise ValueError(f'Invalid listen port - {e}') + if demisto.command() == 'test-module': + return_results("ok") + elif demisto.command() == 'long-running-execution': + demisto.debug('Started long-running-execution.') + while True: + server_config = setup_server() + if not server_config: + raise DemistoException('Failed to configure server.') + try: + uvicorn.run(app, host='0.0.0.0', port=port, log_config=server_config.log_config, **server_config.ssl_args) + except Exception as e: + demisto.error(f'An error occurred in the long running loop: {str(e)} - {format_exc()}') + demisto.updateModuleHealth(f'An error occurred: {str(e)}') + finally: + unlink_certificate(server_config.certificate_path, server_config.private_key_path) + else: + raise NotImplementedError(f'Command {demisto.command()} is not implemented.') + except Exception as e: + demisto.error(format_exc()) + return_error(f'Failed to execute {demisto.command()} command. Error: {e}') + + +if __name__ in ('__main__', '__builtin__', 'builtins'): + main() diff --git a/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener.yml b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener.yml new file mode 100644 index 000000000000..f554c661c8f7 --- /dev/null +++ b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener.yml @@ -0,0 +1,73 @@ +category: Messaging and Conferencing +sectionOrder: +- Connect +- Collect +commonfields: + id: AWS-SNS-Listener + version: -1 +configuration: +- display: Long running instance + defaultvalue: 'true' + name: longRunning + type: 8 + hidden: true + section: Connect + advanced: true + required: false +- additionalinfo: "Runs the service on this port from within Cortex XSOAR. Requires a unique port for each long-running integration instance. Do not use the same port for multiple instances. Note: If you click the test button more than once, a failure may occur mistakenly indicating that the port is already in use. (For Cortex XSOAR 8 and Cortex XSIAM) If you do not enter a Listen Port, an unused port for AWS SNS Listener will automatically be generated when the instance is saved. However, if using an engine, you must enter a Listen Port." + display: Listen Port + name: longRunningPort + type: 0 + required: false + section: Connect +- additionalinfo: Uses basic authentication for accessing the list. If empty, no authentication is enforced. (For Cortex XSOAR 8 and Cortex XSIAM) Optional for engines, otherwise mandatory. + display: Username + name: credentials + type: 9 + section: Connect + required: false +- additionalinfo: "Set the endpoint of your listener. example: /snsv2" + display: Endpoint + name: endpoint + type: 0 + section: Connect + required: false +- display: Certificate (Required for HTTPS) + additionalinfo: "(For Cortex XSOAR 6.x) For use with HTTPS - the certificate that the service should use. (For Cortex XSOAR 8 and Cortex XSIAM) Custom certificates are not supported." + name: certificate + type: 12 + section: Connect + required: false +- display: Private Key (Required for HTTPS) + additionalinfo: "(For Cortex XSOAR 6.x) For use with HTTPS - the private key that the service should use. (For Cortex XSOAR 8 and Cortex XSIAM) When using an engine, configure a private API key. Not supported on the Cortex XSOAR​​ or Cortex XSIAM server." + name: key + type: 14 + section: Connect + required: false +- additionalinfo: "Because this is a push-based integration, it cannot fetch sample events in the mapping wizard. After you finish mapping, it is recommended to turn off the sample events storage to reduce performance overhead." + display: Store sample events for mapping + name: store_samples + type: 8 + section: Connect + required: false +- display: Use system proxy settings + name: proxy + type: 8 + section: Connect + advanced: true + required: false +description: 'Amazon Simple Notification Service (SNS) is a managed service that provides message delivery from publishers to subscribers.' +display: AWS-SNS-Listener +name: AWS-SNS-Listener +script: + commands: [] + dockerimage: demisto/fastapi:1.0.0.87576 + longRunning: true + longRunningPort: true + script: '-' + subtype: python3 + type: python + isFetchSamples: true +fromversion: 6.10.0 +tests: +- AWS SNS Listener - Test diff --git a/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_description.md b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_description.md new file mode 100644 index 000000000000..8d4d6f80c3b9 --- /dev/null +++ b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_description.md @@ -0,0 +1,32 @@ +## AWS-SNS-Listener Help + +In order to configure the AWS-SNS-Listener + +XSOAR6 + +* http: configure an endpoint and a free port for the internal long running server. +* https: In addition to http configuration please add a CA certificate and private +* key AWS-SNS works only with CA certificates. +* Another option is via engine. + +Configuring the subscriber on AWS-SNS UI is straightforward: +http/https://:/ +For more general information on long running integrations on XSOAR6: +https://xsoar.pan.dev/docs/reference/articles/long-running-invoke + +XSOAR8 or XSIAM: + +* The instance should be configured to run only on HTTP. +* The instance is using the HTTPS certificate of the server. +* Please set a user and password (can be global via long running integrations configurations) +* or local for this integration only. + +Configuring the subscriber on AWS-SNS UI: +https://@ext-/xsoar/instance/execute/ + +example: +https://user:pass@ext-myxsoar-address/xsoar/instance/execute/My-AWS-SNS-Listener/sns_ep + +For more info on long running integrations on XSOAR8 or XSIAM: +https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8/Cortex-XSOAR-Administrator-Guide/Forward-Requests-to-Long-Running-Integrations + diff --git a/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_image.png b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_image.png new file mode 100644 index 0000000000000000000000000000000000000000..e2af23f59a4ed639a62d0dde10db58e702e34c1c GIT binary patch literal 4986 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 Ef)SOZ%>V!Z literal 0 HcmV?d00001 diff --git a/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_test.py b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_test.py new file mode 100644 index 000000000000..9a6f91da2418 --- /dev/null +++ b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/AWSSNSListener_test.py @@ -0,0 +1,113 @@ +import pytest +from AWSSNSListener import handle_notification, is_valid_sns_message, is_valid_integration_credentials +from unittest.mock import patch +import requests + +VALID_PAYLOAD = { + "Type": "Notification", + "MessageId": "uuid", + "TopicArn": "topicarn", + "Subject": "NotificationSubject", + "Message": "NotificationMessage", + "Timestamp": "2024-02-13T18:03:27.239Z", + "SignatureVersion": "1", + "Signature": b"sign", + "SigningCertURL": "https://link.pem", +} + + +@pytest.fixture +def mock_params(mocker): + return mocker.patch('AWSSNSListener.PARAMS', new={'credentials': {'identifier': 'foo', 'password': 'bar'}}, + autospec=False) + + +def test_handle_notification_valid(): + ''' + Given a valid SNS notification message + When handle_notification is called with the message and raw json + Then should parse to a valid incident + ''' + raw_json = {} + expected_notification = { + 'name': 'NotificationSubject', + 'labels': [], + 'rawJSON': raw_json, + 'occurred': '2024-02-13T18:03:27.239Z', + 'details': 'ExternalID:uuid TopicArn:topicarn Message:NotificationMessage', + 'type': 'AWS-SNS Notification' + } + + actual_incident = handle_notification(VALID_PAYLOAD, raw_json) + + assert actual_incident == expected_notification + + +@patch("AWSSNSListener.client") +@patch("AWSSNSListener.X509") +@patch("M2Crypto.EVP.PKey") +def test_is_valid_sns_message(mock_client, mock_x509, mock_PKey): + mock_resp = requests.models.Response() + mock_resp.status_code = 200 + response_content = '''-----BEGIN VALID CERTIFICATE----- + -----END CERTIFICATE-----''' + mock_resp._content = str.encode(response_content) + mock_client.get.return_value = mock_resp + mock_PKey.verify_final.return_value = 1 + mock_x509.get_pubkey.return_value = mock_PKey + mock_x509.load_cert_string.return_value = mock_x509 + is_valid = is_valid_sns_message(VALID_PAYLOAD) + assert is_valid + + +@patch("AWSSNSListener.client") +@patch("AWSSNSListener.X509") +@patch("M2Crypto.EVP.PKey") +def test_not_valid_sns_message(mock_client, mock_x509, mock_PKey, capfd): + mock_resp = requests.models.Response() + mock_resp.status_code = 200 + response_content = '''-----BEGIN INVALID CERTIFICATE----- + -----END CERTIFICATE-----''' + mock_resp._content = str.encode(response_content) + mock_client.get.return_value = mock_resp + mock_PKey.verify_final.return_value = 2 + mock_x509.get_pubkey.return_value = mock_PKey + mock_x509.load_cert_string.return_value = mock_x509 + with capfd.disabled(): + is_valid = is_valid_sns_message(VALID_PAYLOAD) + assert is_valid is False + + +@patch('fastapi.security.http.HTTPBasicCredentials') +def test_valid_credentials(mock_httpBasicCredentials, mock_params): + """ + Given valid credentials, request headers and token + When is_valid_integration_credentials is called + Then it should return True, header_name + """ + mock_httpBasicCredentials.username = 'foo' + mock_httpBasicCredentials.password = 'bar' + request_headers = {} + token = "sometoken" + result, header_name = is_valid_integration_credentials( + mock_httpBasicCredentials, request_headers, token + ) + assert result is True + assert header_name is None + + +@patch('fastapi.security.http.HTTPBasicCredentials') +def test_invalid_credentials(mock_httpBasicCredentials, mock_params): + """ + Given invalid credentials, request headers and token + When is_valid_integration_credentials is called + Then it should return True, header_name + """ + mock_httpBasicCredentials.username = 'foot' + mock_httpBasicCredentials.password = 'bark' + request_headers = {} + token = "sometoken" + result, header_name = is_valid_integration_credentials( + mock_httpBasicCredentials, request_headers, token + ) + assert result is False diff --git a/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/README.md b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/README.md new file mode 100644 index 000000000000..2afae159959c --- /dev/null +++ b/Packs/AWS-SNS-Listener/Integrations/AWSSNSListener/README.md @@ -0,0 +1,27 @@ +Amazon Simple Notification Service (SNS) is a managed service that provides message delivery from publishers to subscribers. +This integration was integrated and tested with version January 2024 of AWS-SNS-Listener. + +## Configure AWS-SNS-Listener on Cortex XSOAR + +1. Navigate to **Settings** > **Integrations** > **Servers & Services**. +2. Search for AWS-SNS-Listener. +3. Click **Add instance** to create and configure a new integration instance. + + | **Parameter** | **Description** | **Required** | + | --- | --- | --- | + | Long running instance | | False | + | Listen Port | Runs the service on this port from within Cortex XSOAR. Requires a unique port for each long-running integration instance. Do not use the same port for multiple instances. Note: If you click the test button more than once, a failure may occur mistakenly indicating that the port is already in use. \(For Cortex XSOAR 8 and Cortex XSIAM\) If you do not enter a Listen Port, an unused port for AWS SNS Listener will automatically be generated when the instance is saved. However, if using an engine, you must enter a Listen Port. | False | + | Username | Uses basic authentication for accessing the list. If empty, no authentication is enforced. \(For Cortex XSOAR 8 and Cortex XSIAM\) Optional for engines, otherwise mandatory. | False | + | Password | | False | + | Endpoint | Set the endpoint of your listener. example: /snsv2 | False | + | Certificate (Required for HTTPS) | \(For Cortex XSOAR 6.x\) For use with HTTPS - the certificate that the service should use. \(For Cortex XSOAR 8 and Cortex XSIAM\) Custom certificates are not supported. | False | + | Private Key (Required for HTTPS) | \(For Cortex XSOAR 6.x\) For use with HTTPS - the private key that the service should use. \(For Cortex XSOAR 8 and Cortex XSIAM\) When using an engine, configure a private API key. Not supported on the Cortex XSOAR​​ or Cortex XSIAM server. | False | + | Store sample events for mapping | Because this is a push-based integration, it cannot fetch sample events in the mapping wizard. After you finish mapping, it is recommended to turn off the sample events storage to reduce performance overhead. | False | + | Use system proxy settings | | False | + +4. Click **Test** to validate the URLs, token, and connection. + +## Commands + +You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. +After you successfully execute a command, a DBot message appears in the War Room with the command details. diff --git a/Packs/AWS-SNS-Listener/README.md b/Packs/AWS-SNS-Listener/README.md new file mode 100644 index 000000000000..246c33a23f0f --- /dev/null +++ b/Packs/AWS-SNS-Listener/README.md @@ -0,0 +1,6 @@ +Amazon Simple Notification Service (SNS) is a managed service that provides message delivery from publishers to subscribers. Publishers communicate asynchronously with subscribers by sending messages to a topic, which is a logical access point and communication channel. Clients can subscribe to the SNS topic and receive published messages using a supported endpoint type, such as Amazon Kinesis Data Firehose, Amazon SQS, AWS Lambda, HTTP, email, mobile push notifications, and mobile text messages (SMS). + +## What does this pack do +The AWS SNS Listener supports two types of POST requests: +* SubscriptionConfirmation: Extract the subscription URL send subscription confirmation. +* Notification: Extract the subject and message body and creates a Cortex XSOAR / Cortex XSIAM incident. \ No newline at end of file diff --git a/Packs/AWS-SNS-Listener/TestPlaybooks/AWS_SNS_Listener_-_Test.yml b/Packs/AWS-SNS-Listener/TestPlaybooks/AWS_SNS_Listener_-_Test.yml new file mode 100644 index 000000000000..11365dfe5b51 --- /dev/null +++ b/Packs/AWS-SNS-Listener/TestPlaybooks/AWS_SNS_Listener_-_Test.yml @@ -0,0 +1,385 @@ +id: AWS SNS Listener - Test +version: -1 +name: AWS SNS Listener - Test +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: 976ffcfd-467b-4c2a-82ee-9285ddb6d84a + type: start + task: + id: 976ffcfd-467b-4c2a-82ee-9285ddb6d84a + version: -1 + name: "" + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "6" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 50 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "1": + id: "1" + taskid: 89106f4b-7057-44e3-81d0-5715f937de6d + type: regular + task: + id: 89106f4b-7057-44e3-81d0-5715f937de6d + version: -1 + name: Post a msg to SNS-Listener + description: Sends http request. Returns the response as json. + scriptName: http + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "7" + scriptarguments: + body: + simple: |- + {"Type": "Notification", + "MessageId": "afe031bb-5ef5-53b1-b1ad-6c4a4288defb", + "TopicArn": "arn:aws:sns:eu-central-1:test:test", + "Subject": "SNS-test-subject", + "Message": "SNS-test-message body", + "Timestamp": "2023-12-11T14:18:37.923Z", + "SignatureVersion": "1", + "Signature": "Signature_test", + "SigningCertURL": "https://sns.eu-central-1.amazonaws.com/SimpleNotificationService-01d088a6f77103d0fe307c0069e40ed6.pem", + "UnsubscribeURL": "https://sns.eu-central-1.amazonaws.com/?Action=Unsubscribe" + } + headers: + simple: Authorization:token + method: + simple: POST + url: + simple: http://localhost:9000/incident/aws/ + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 545 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "2": + id: "2" + taskid: 38bf8674-3546-47e1-8d8f-8c921e45733a + type: regular + task: + id: 38bf8674-3546-47e1-8d8f-8c921e45733a + version: -1 + name: Search the incident + description: Searches Demisto incidents + scriptName: SearchIncidentsV2 + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "3" + scriptarguments: + name: + simple: SNS-test-subject + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 1070 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "3": + id: "3" + taskid: 0ee4c9b7-8a4b-4c59-8064-d01b5214d888 + type: condition + task: + id: 0ee4c9b7-8a4b-4c59-8064-d01b5214d888 + version: -1 + name: Verify incident was created successfully + type: condition + iscommand: false + brand: "" + nexttasks: + "yes": + - "4" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isExists + left: + value: + simple: foundIncidents.id + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 1245 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "4": + id: "4" + taskid: 3daf5a1f-bf67-474d-8a4e-c63f02eb544c + type: regular + task: + id: 3daf5a1f-bf67-474d-8a4e-c63f02eb544c + version: -1 + name: Close webhook triggered incident + description: commands.local.cmd.close.inv + script: Builtin|||closeInvestigation + type: regular + iscommand: true + brand: Builtin + nexttasks: + '#none#': + - "10" + scriptarguments: + id: + simple: ${foundIncidents.id} + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 1420 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "6": + id: "6" + taskid: 5bf72787-3920-4dd6-87c2-11e307629d7c + type: regular + task: + id: 5bf72787-3920-4dd6-87c2-11e307629d7c + version: -1 + name: DeleteContext + description: Delete field from context + scriptName: DeleteContext + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "8" + scriptarguments: + all: + simple: "yes" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 195 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "7": + id: "7" + taskid: 813fcb90-ff23-4e50-80df-48cc4890cf29 + type: condition + task: + id: 813fcb90-ff23-4e50-80df-48cc4890cf29 + version: -1 + name: Verify Success HTTP Response + type: condition + iscommand: false + brand: "" + nexttasks: + "yes": + - "9" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isEqualNumber + left: + value: + simple: HttpRequest.Response.StatusCode + iscontext: true + right: + value: + simple: "200" + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 720 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "8": + id: "8" + taskid: 813e76da-af96-4d95-8d93-fe10e0a71e56 + type: regular + task: + id: 813e76da-af96-4d95-8d93-fe10e0a71e56 + version: -1 + name: Sleep 10 seconds to let the webserver spin up + description: Sleep for X seconds + scriptName: Sleep + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "1" + scriptarguments: + seconds: + simple: "10" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 370 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "9": + id: "9" + taskid: 2bb0bae1-4241-4c88-8d85-ebe7c1586580 + type: regular + task: + id: 2bb0bae1-4241-4c88-8d85-ebe7c1586580 + version: -1 + name: Sleep 10 seconds before searching the incident + description: Sleep for X seconds + scriptName: Sleep + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "2" + scriptarguments: + seconds: + simple: "10" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 895 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "10": + id: "10" + taskid: d5fbc51b-96bc-4723-8c71-ff960b4eab70 + type: title + task: + id: d5fbc51b-96bc-4723-8c71-ff960b4eab70 + version: -1 + name: Done + type: title + iscommand: false + brand: "" + description: '' + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 50, + "y": 1580 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false +view: |- + { + "linkLabelsPosition": {}, + "paper": { + "dimensions": { + "height": 1595, + "width": 380, + "x": 50, + "y": 50 + } + } + } +inputs: [] +outputs: [] +fromversion: 6.10.0 +description: '' diff --git a/Packs/AWS-SNS-Listener/pack_metadata.json b/Packs/AWS-SNS-Listener/pack_metadata.json new file mode 100644 index 000000000000..b506aa119a11 --- /dev/null +++ b/Packs/AWS-SNS-Listener/pack_metadata.json @@ -0,0 +1,22 @@ +{ + "name": "AWS-SNS-Listener", + "description": "A long running AWS SNS Listener service that can subscribe to an SNS topic and create incidents from the messages received.", + "support": "xsoar", + "currentVersion": "1.0.0", + "author": "Cortex XSOAR", + "url": "https://www.paloaltonetworks.com/cortex", + "email": "", + "created": "2023-01-12T00:00:00Z", + "categories": [ + "Cloud Services" + ], + "tags": [], + "useCases": [], + "keywords": [ + "Amazon" + ], + "marketplaces": [ + "xsoar", + "marketplacev2" + ] +} \ No newline at end of file diff --git a/Packs/Base/ReleaseNotes/1_33_32.md b/Packs/Base/ReleaseNotes/1_33_32.md new file mode 100644 index 000000000000..30a4e223365c --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_33_32.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### CommonServerPython + +- Added support for long running integrations handle proxies. diff --git a/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py b/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py index e3642a550c23..e44e32aff057 100644 --- a/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py +++ b/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py @@ -826,6 +826,42 @@ def add_http_prefix_if_missing(address=''): return 'http://' + address +def handle_proxy_for_long_running(proxy_param_name='proxy', checkbox_default_value=False, handle_insecure=True, + insecure_param_name=None): + """ + Handle logic for long running integration routing traffic through the system proxy. + Should usually be called at the beginning of the integration, depending on proxy checkbox state. + Long running integrations on hosted tenants XSOAR8 and XSIAM has a dedicated env. var.: CRTX_HTTP_PROXY. + Fallback call to handle_proxy in cases long running integration on engine or XSOAR6 + + :type proxy_param_name: ``string`` + :param proxy_param_name: name of the "use system proxy" integration parameter + + :type checkbox_default_value: ``bool`` + :param checkbox_default_value: Default value of the proxy param checkbox + + :type handle_insecure: ``bool`` + :param handle_insecure: Whether to check the insecure param and unset env variables + + :type insecure_param_name: ``string`` + :param insecure_param_name: Name of insecure param. If None will search insecure and unsecure + + :return: proxies dict for the 'proxies' parameter of 'requests' functions and use_ssl boolean + :rtype: ``Tuple[dict, boolean]`` + """ + proxies = {} + crtx_http_proxy = os.environ.get('CRTX_HTTP_PROXY', None) + if crtx_http_proxy: + demisto.error('Setting proxies according to CRTX_HTTP_PROXY: {}'.format(crtx_http_proxy)) + proxies = { + 'http': crtx_http_proxy, + 'https': crtx_http_proxy + } + handle_insecure = True + return proxies, handle_insecure + return handle_proxy(proxy_param_name, checkbox_default_value, handle_insecure, insecure_param_name), handle_insecure + + def handle_proxy(proxy_param_name='proxy', checkbox_default_value=False, handle_insecure=True, insecure_param_name=None): """ diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index c303b18714ef..21eda318c044 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.33.31", + "currentVersion": "1.33.32", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", diff --git a/Tests/conf.json b/Tests/conf.json index b6e5283ce38e..fdc83215ea3d 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -5675,6 +5675,11 @@ { "integrations": "Zimperium v2", "playbookID": "Zimperiumv2-TestPlaybook" + }, + { + "integrations": "AWS-SNS-Listener", + "playbookID": "AWS SNS Listener - Test", + "instance_names": "AWS-SNS-Listener" } ], "skipped_tests": { @@ -5859,7 +5864,8 @@ "OpsGenieV3TestPlaybook": "Issue CIAC-7649", "ThreatStream-Test": "Issue CRTX-96526", "MSG-Threat-Assessment-test": "API limitation", - "BambenekConsultingFeed_Test": "Issue CRTX-99480" + "BambenekConsultingFeed_Test": "Issue CRTX-99480", + "AWS SNS Listener - Test": "Cant validate mock msg against AWS-SNS in TBP" }, "skipped_integrations": { "EWS Mail Sender": "The integration is deprecated", From ec9e097c6f4cd12b34467334683b992d8168b804 Mon Sep 17 00:00:00 2001 From: Guy Afik <53861351+GuyAfik@users.noreply.github.com> Date: Mon, 19 Feb 2024 09:49:53 +0200 Subject: [PATCH 022/272] [Slack v3] - add support for file-mirroring from xsoar to slack (#32611) * logs * mirror files from xsoar to slack * start implementing mirror from slack to xsoar * mirror from slack to xsoar - in progress * use http-request for mirroring slack files to xsoar * revert enable_dm param * revert csp changes * handle ssl errors * add context * revert mirror from slack to xsoar * add test * bump rn * type ignore * add comment handling and fix test * update param location * bump docker * rn * update docs * fix test * update rn * update disclaimer * Bump pack from version Slack to 3.4.6. --------- Co-authored-by: Content Bot --- Packs/Slack/Integrations/SlackV3/README.md | 47 ++++++++--------- Packs/Slack/Integrations/SlackV3/SlackV3.py | 51 ++++++++++++++++--- Packs/Slack/Integrations/SlackV3/SlackV3.yml | 10 +++- .../Integrations/SlackV3/SlackV3_test.py | 38 ++++++++++++++ Packs/Slack/ReleaseNotes/3_4_6.md | 8 +++ Packs/Slack/pack_metadata.json | 2 +- 6 files changed, 123 insertions(+), 33 deletions(-) create mode 100644 Packs/Slack/ReleaseNotes/3_4_6.md diff --git a/Packs/Slack/Integrations/SlackV3/README.md b/Packs/Slack/Integrations/SlackV3/README.md index c35bf51b0820..4157ea5de9f0 100644 --- a/Packs/Slack/Integrations/SlackV3/README.md +++ b/Packs/Slack/Integrations/SlackV3/README.md @@ -15,30 +15,31 @@ to learn about configuring SlackV3 using the app manifest. 2. Search for SlackV3. 3. Click **Add instance** to create and configure a new integration instance. - | **Parameter** | **Description** | **Required** | - |---|---|---| - | `bot_token` | Slack API bot token. | False | - | `user_token` | Slack API user token. | False | - | `app_token` | Slack API app token. | False | - | `incidentNotificationChannel` | Dedicated Slack channel to receive notifications. | False | - | `min_severity` | Minimum incident severity by which to send messages to Slack. | False | - | `incidentType` | Type of incidents created in Slack. | False | - | `allow_incidents` | Allow external users to create incidents via direct messages. | False | - | `proxy` | Use system proxy settings. | False | - | `unsecure` | Trust any certificate (not secure). Make sure to mark this parameter if you want the SlackBlockBuilder script to send a response back to the incident context. | False | - | `longRunning` | Long running instance. Required for investigation mirroring and direct messages. | False | - | `bot_name` | Bot display name in Slack (Cortex XSOAR by default). | False | - | `bot_icon` | Bot icon in Slack - Image URL (Cortex XSOAR icon by default). | False | - | `max_limit_time` | Maximum time to wait for a rate limiting call in seconds. | False | - | `paginated_count` | Number of objects to return in each paginated call. | False | - | `proxy_url` | Proxy URL to use in Slack API calls. | False | - | `filtered_tags` | Comma-separated list of tags by which to filter the messages sent from Cortex XSOAR. Only supported in Cortex XSOAR V6.1 and above. | False | - | `permitted_notifications` | Types of notifications to send (to individual users and to the dedicated Slack channel, if specified). | False | - | `common_channels` | For workspaces where a handful of channels are consistently being used, you may add them as a CSV in the format ChannelName:ChannelID. | False | + | **Parameter** | **Description** | **Required** | + |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---| + | `bot_token` | Slack API bot token. | False | + | `user_token` | Slack API user token. | False | + | `app_token` | Slack API app token. | False | + | `incidentNotificationChannel` | Dedicated Slack channel to receive notifications. | False | + | `min_severity` | Minimum incident severity by which to send messages to Slack. | False | + | `incidentType` | Type of incidents created in Slack. | False | + | `allow_incidents` | Allow external users to create incidents via direct messages. | False | + | `proxy` | Use system proxy settings. | False | + | `unsecure` | Trust any certificate (not secure). Make sure to mark this parameter if you want the SlackBlockBuilder script to send a response back to the incident context. | False | + | `longRunning` | Long running instance. Required for investigation mirroring and direct messages. | False | + | `bot_name` | Bot display name in Slack (Cortex XSOAR by default). | False | + | `bot_icon` | Bot icon in Slack - Image URL (Cortex XSOAR icon by default). | False | + | `max_limit_time` | Maximum time to wait for a rate limiting call in seconds. | False | + | `paginated_count` | Number of objects to return in each paginated call. | False | + | `proxy_url` | Proxy URL to use in Slack API calls. | False | + | `filtered_tags` | Comma-separated list of tags by which to filter the messages sent from Cortex XSOAR. Only supported in Cortex XSOAR V6.1 and above. | False | + | `permitted_notifications` | Types of notifications to send (to individual users and to the dedicated Slack channel, if specified). | False | + | `common_channels` | For workspaces where a handful of channels are consistently being used, you may add them as a CSV in the format ChannelName:ChannelID. | False | | `disable_caching` | When configured, Disable Caching will prevent the integration from paginating to search for Users or Conversations. Additionally, it will prevent excess data from being stored to the integration context. If this parameter is disabled, the instance may create high memory usage. | False | - | `mirroring` | Enable Incident Mirroring. | False | - | `ignore_event_retries` | In some cases, events may not be processed fast enough. If you wish to attempt to retry the event, select `false`. Note that this can result in some responses being double-posted. Default is `True`. | False | - | `extensive_logging` | Extensive Logging. This parameter will write additional data to the logs and should only be used when you are directed to by XSOAR support. | False | + | `mirroring` | Enable Incident Mirroring. | False | + | `enable_outbound_file_mirroring` | Enable Outbound File Mirroring. Whether to enable mirroring from xsoar to slack, mark it file mirroring is required in investigations. | False | + | `ignore_event_retries` | In some cases, events may not be processed fast enough. If you wish to attempt to retry the event, select `false`. Note that this can result in some responses being double-posted. Default is `True`. | False | + | `extensive_logging` | Extensive Logging. This parameter will write additional data to the logs and should only be used when you are directed to by XSOAR support. | False | 5. Click **Test** to validate the URLs, token, and connection. diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3.py b/Packs/Slack/Integrations/SlackV3/SlackV3.py index fdfda5228f74..bd0a3318dd78 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3.py +++ b/Packs/Slack/Integrations/SlackV3/SlackV3.py @@ -85,6 +85,7 @@ CACHED_INTEGRATION_CONTEXT: dict CACHE_EXPIRY: float MIRRORING_ENABLED: bool +FILE_MIRRORING_ENABLED: bool LONG_RUNNING_ENABLED: bool DEMISTO_API_KEY: str DEMISTO_URL: str @@ -1767,6 +1768,31 @@ def get_conversation_by_name(conversation_name: str) -> dict: return conversation +def send_mirrored_file_to_slack(entry: str, message: str, original_channel: str, channel_id: str, comment: Optional[str] = None): + """ + Sends a file from xsoar investigation to a mirrored slack channel + + Args: + entry: the entry ID of the file + message: the message from the war-room when uploading file + original_channel: the channel name to upload the file + channel_id: the channel ID to upload the file + comment: a comment that was added when uploading the file + """ + file_name = demisto.getFilePath(entry)["name"] + if FILE_MIRRORING_ENABLED: + demisto.debug( + f'file {file_name} has been uploaded to a mirrored incident, ' + f'uploading the file to slack channel {original_channel}' + ) + if comment: + # if a comment was added when uploading the file, add it to the message + message = f'{message}\nComment: {comment}' + slack_send_file(original_channel, channel_id, entry, message) + else: + demisto.debug(f'file {file_name} will not be mirrored because file mirroring is not enabled') + + def slack_send(): """ Sends a message to slack @@ -1807,6 +1833,16 @@ def slack_send(): if tags and not any(elem in entry_tags for elem in tags): return + if entry: + send_mirrored_file_to_slack( + entry, + message=message, + original_channel=original_channel, + channel_id=channel_id, + comment=entry_object.get("contents") + ) + return + if (to and group) or (to and original_channel) or (to and original_channel and group): return_error('Only one destination can be provided.') @@ -1910,17 +1946,17 @@ def save_entitlement(entitlement, thread, reply, expiry, default_response): set_to_integration_context_with_retries({'questions': questions}, OBJECTS_TO_KEYS, SYNC_CONTEXT) -def slack_send_file(): +def slack_send_file(_channel: str | None = None, _channel_id: str = '', _entry_id: str | None = None, _comment: str = ""): """ Sends a file to slack """ to = demisto.args().get('to') - channel = demisto.args().get('channel') - channel_id = demisto.args().get('channel_id', '') + channel = _channel or demisto.args().get('channel') + channel_id = _channel_id or demisto.args().get('channel_id', '') group = demisto.args().get('group') - entry_id = demisto.args().get('file') + entry_id = _entry_id or demisto.args().get('file') thread_id = demisto.args().get('threadID') - comment = demisto.args().get('comment', '') + comment = _comment or demisto.args().get('comment', '') if not (to or channel or group): mirror = find_mirror_by_investigation() @@ -2747,7 +2783,7 @@ def init_globals(command_name: str = ''): """ global BOT_TOKEN, PROXY_URL, PROXIES, DEDICATED_CHANNEL, CLIENT, USER_CLIENT, \ - CACHED_INTEGRATION_CONTEXT, MIRRORING_ENABLED, USER_TOKEN + CACHED_INTEGRATION_CONTEXT, MIRRORING_ENABLED, FILE_MIRRORING_ENABLED, USER_TOKEN global SEVERITY_THRESHOLD, ALLOW_INCIDENTS, INCIDENT_TYPE, VERIFY_CERT, ENABLE_DM, BOT_ID, CACHE_EXPIRY global BOT_NAME, BOT_ICON_URL, MAX_LIMIT_TIME, PAGINATED_COUNT, SSL_CONTEXT, APP_TOKEN, ASYNC_CLIENT global DEFAULT_PERMITTED_NOTIFICATION_TYPES, CUSTOM_PERMITTED_NOTIFICATION_TYPES, PERMITTED_NOTIFICATION_TYPES @@ -2784,6 +2820,7 @@ def init_globals(command_name: str = ''): CUSTOM_PERMITTED_NOTIFICATION_TYPES = demisto.params().get('permitted_notifications', []) PERMITTED_NOTIFICATION_TYPES = DEFAULT_PERMITTED_NOTIFICATION_TYPES + CUSTOM_PERMITTED_NOTIFICATION_TYPES MIRRORING_ENABLED = demisto.params().get('mirroring', True) + FILE_MIRRORING_ENABLED = demisto.params().get('enable_outbound_file_mirroring', False) LONG_RUNNING_ENABLED = demisto.params().get('longRunning', True) DEMISTO_API_KEY = demisto.params().get('demisto_api_key', {}).get('password', '') demisto_urls = demisto.demistoUrls() @@ -2949,7 +2986,7 @@ def main() -> None: if EXTENSIVE_LOGGING: os.environ['PYTHONASYNCIODEBUG'] = "1" support_multithreading() - command_func() + command_func() # type: ignore except Exception as e: demisto.debug(e) return_error(str(e)) diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3.yml b/Packs/Slack/Integrations/SlackV3/SlackV3.yml index c548bcba78c6..409d2532aaca 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3.yml +++ b/Packs/Slack/Integrations/SlackV3/SlackV3.yml @@ -103,8 +103,14 @@ configuration: display: Enable Incident Mirroring name: mirroring type: 8 - section: Collect + section: Connect + required: false +- display: Enable Outbound File Mirroring + name: enable_outbound_file_mirroring + type: 8 + section: Connect required: false + additionalinfo: Whether to enable mirroring only from xsoar to slack, mark it if file mirroring is required in investigations. - defaultvalue: 'true' display: Long running instance. Required for investigation mirroring and direct messages. name: longRunning @@ -492,7 +498,7 @@ script: description: Set this argument to specify how many results to return. description: Retrieves replies to specific messages, regardless of whether it's from a public or private channel, direct message, or otherwise. name: slack-get-conversation-replies - dockerimage: demisto/slackv3:1.0.0.86601 + dockerimage: demisto/slackv3:1.0.0.87650 longRunning: true runonce: false script: '-' diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3_test.py b/Packs/Slack/Integrations/SlackV3/SlackV3_test.py index bc8cbce14047..5554b9457304 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3_test.py +++ b/Packs/Slack/Integrations/SlackV3/SlackV3_test.py @@ -2835,6 +2835,44 @@ def api_call(method: str, http_verb: str = 'POST', file: str = None, params=None assert demisto.getIntegrationContext()['questions'] == js.dumps(questions) +def test_slack_send_with_mirrored_file(mocker): + """ + Given: + - mirror entry which is basically a file + + When: + - running send-notification triggered from mirroring + + Then: + - Validate that the file is sent successfully + """ + import SlackV3 + + mocker.patch.object(demisto, 'params', return_value={'enable_outbound_file_mirroring': True}) + + SlackV3.init_globals() + + mocker.patch.object( + demisto, + 'args', + return_value={ + "message": "test", + "channel_id": "1234", + "channel": "channel", + "entry": "1234", + "messageType": SlackV3.MIRROR_TYPE, + "entryObject": {} + } + ) + slack_send_request = mocker.patch.object(SlackV3, 'slack_send_request', return_value='file-sent') + demisto_results = mocker.patch.object(demisto, 'results') + + SlackV3.slack_send() + assert slack_send_request.call_args_list[0].kwargs["file_dict"] + assert slack_send_request.call_args_list[0].kwargs["channel_id"] == "1234" + assert demisto_results.call_args_list[0][0][0] == 'File sent to Slack successfully.' + + def test_send_request_with_entitlement_blocks(mocker): import SlackV3 diff --git a/Packs/Slack/ReleaseNotes/3_4_6.md b/Packs/Slack/ReleaseNotes/3_4_6.md new file mode 100644 index 000000000000..747b2021976d --- /dev/null +++ b/Packs/Slack/ReleaseNotes/3_4_6.md @@ -0,0 +1,8 @@ + +#### Integrations + +##### Slack v3 + +- Added support for mirroring files from xsoar to slack. +- Added the **Enable Outbound File Mirroring** integration parameter to allow file mirroring from xsoar to slack. The parameter is unchecked by default, disabling file mirroring. +- Updated the Docker image to: *demisto/slackv3:1.0.0.87650*. diff --git a/Packs/Slack/pack_metadata.json b/Packs/Slack/pack_metadata.json index ec314bf3d144..29638ec27709 100644 --- a/Packs/Slack/pack_metadata.json +++ b/Packs/Slack/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Slack", "description": "Interact with Slack API - collect logs, send messages and notifications to your Slack team.", "support": "xsoar", - "currentVersion": "3.4.5", + "currentVersion": "3.4.6", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From c7e7a80ad9b5fb489bcc01fc95deca98778c12b5 Mon Sep 17 00:00:00 2001 From: JudithB <132264628+jbabazadeh@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:23:01 +0200 Subject: [PATCH 023/272] Qradar reference sets list issue (#32779) * fix qradar-reference-sets-list to able use ref_name with filter and range * Bump pack from version QRadar to 2.4.49. * filter description * Update QRadar_v3.py * RN * RN --------- Co-authored-by: Content Bot --- Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.py | 4 ++-- Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.yml | 4 +++- Packs/QRadar/ReleaseNotes/2_4_50.md | 7 +++++++ Packs/QRadar/pack_metadata.json | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 Packs/QRadar/ReleaseNotes/2_4_50.md diff --git a/Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.py b/Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.py index d63a4c96ac07..df63a9618081 100644 --- a/Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.py +++ b/Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.py @@ -587,8 +587,8 @@ def search_results_get(self, search_id: str, range_: Optional[str] = None): def reference_sets_list(self, range_: Optional[str] = None, ref_name: Optional[str] = None, filter_: Optional[str] = None, fields: Optional[str] = None): name_suffix = f'/{parse.quote(ref_name, safe="")}' if ref_name else '' - params = assign_params(fields=fields) if ref_name else assign_params(filter=filter_, fields=fields) - additional_headers = {'Range': range_} if not ref_name else None + params = assign_params(filter=filter_, fields=fields) + additional_headers = {'Range': range_} return self.http_request( method='GET', url_suffix=f'/reference_data/sets{name_suffix}', diff --git a/Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.yml b/Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.yml index ea8e6120b9f8..5e7727e755ae 100644 --- a/Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.yml +++ b/Packs/QRadar/Integrations/QRadar_v3/QRadar_v3.yml @@ -927,7 +927,9 @@ script: description: 'Range of results to return (e.g.: 0-20, 3-5, 3-3).' defaultValue: 0-49 - name: filter - description: 'Query by which to filter reference sets, e.g., "timeout_type=FIRST_SEEN". For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html' + description: |- + Query by which to filter reference sets, e.g., "timeout_type=FIRST_SEEN". For reference, see: https://www.ibm.com/support/knowledgecenter/SS42VS_SHR/com.ibm.qradarapi.doc/c_rest_api_filtering.html. + when using both ref_name and filter arguments, the filter should be from the data values of the specified reference set, e.g. "value='1.1.1.1'". - name: fields description: 'Comma-separated list of fields to retrieve in the response. Fields that are not explicitly named are excluded. E.g., "name,timeout_type". Specify subfields in brackets and multiple fields in the same object separated by commas. For a full list of available fields, see: https://ibmsecuritydocs.github.io/qradar_api_14.0/14.0--reference_data-sets-GET.html.' isArray: true diff --git a/Packs/QRadar/ReleaseNotes/2_4_50.md b/Packs/QRadar/ReleaseNotes/2_4_50.md new file mode 100644 index 000000000000..eb447eecfb3b --- /dev/null +++ b/Packs/QRadar/ReleaseNotes/2_4_50.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### IBM QRadar v3 + +- Fixed an issue in **qradar-reference-sets-list** when using the ref_name argument with filter or range arguments didn't effect on the results as expected. +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. \ No newline at end of file diff --git a/Packs/QRadar/pack_metadata.json b/Packs/QRadar/pack_metadata.json index 34f8c663bd2c..e5c36b3a42ca 100644 --- a/Packs/QRadar/pack_metadata.json +++ b/Packs/QRadar/pack_metadata.json @@ -2,7 +2,7 @@ "name": "IBM QRadar", "description": "Fetch offenses as incidents and search QRadar", "support": "xsoar", - "currentVersion": "2.4.49", + "currentVersion": "2.4.50", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e1bdd8de4adf35b9948038cabd3d7c45db9f7608 Mon Sep 17 00:00:00 2001 From: Yaakov Praisler <59408745+yaakovpraisler@users.noreply.github.com> Date: Mon, 19 Feb 2024 16:04:29 +0200 Subject: [PATCH 024/272] [XSUP-33662] Fix Okta Auth0 test-module (#32992) * fixed XSUP-33662 * docker --- .../OktaAuth0EventCollector/OktaAuth0EventCollector.py | 1 - .../OktaAuth0EventCollector/OktaAuth0EventCollector.yml | 2 +- Packs/OktaAuth0/ReleaseNotes/1_0_2.md | 7 +++++++ Packs/OktaAuth0/pack_metadata.json | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 Packs/OktaAuth0/ReleaseNotes/1_0_2.md diff --git a/Packs/OktaAuth0/Integrations/OktaAuth0EventCollector/OktaAuth0EventCollector.py b/Packs/OktaAuth0/Integrations/OktaAuth0EventCollector/OktaAuth0EventCollector.py index 4be960410c6a..1f8730233122 100644 --- a/Packs/OktaAuth0/Integrations/OktaAuth0EventCollector/OktaAuth0EventCollector.py +++ b/Packs/OktaAuth0/Integrations/OktaAuth0EventCollector/OktaAuth0EventCollector.py @@ -174,7 +174,6 @@ def test_module_command(client: Client, params: dict, last_run: dict) -> str: Returns: (str) 'ok' if success. """ - params = prepare_query_params(params) fetch_events_command(client, params, last_run) return 'ok' diff --git a/Packs/OktaAuth0/Integrations/OktaAuth0EventCollector/OktaAuth0EventCollector.yml b/Packs/OktaAuth0/Integrations/OktaAuth0EventCollector/OktaAuth0EventCollector.yml index 34cd8fd3152f..9fbfaf93892f 100644 --- a/Packs/OktaAuth0/Integrations/OktaAuth0EventCollector/OktaAuth0EventCollector.yml +++ b/Packs/OktaAuth0/Integrations/OktaAuth0EventCollector/OktaAuth0EventCollector.yml @@ -61,7 +61,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 marketplaces: - marketplacev2 fromversion: 8.2.0 diff --git a/Packs/OktaAuth0/ReleaseNotes/1_0_2.md b/Packs/OktaAuth0/ReleaseNotes/1_0_2.md new file mode 100644 index 000000000000..9ab4f27c8b27 --- /dev/null +++ b/Packs/OktaAuth0/ReleaseNotes/1_0_2.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Okta Auth0 Event Collector + +- Fixed an issue where the *Test button* failed to generate correct query params for the test. +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/OktaAuth0/pack_metadata.json b/Packs/OktaAuth0/pack_metadata.json index d677c9ef1b2d..a8ea82975386 100644 --- a/Packs/OktaAuth0/pack_metadata.json +++ b/Packs/OktaAuth0/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Okta Auth0", "description": "Identity platform to manage access to your applications.", "support": "xsoar", - "currentVersion": "1.0.1", + "currentVersion": "1.0.2", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 4385426ac38c4d4f83b52379b0ef6553c7e4ebab Mon Sep 17 00:00:00 2001 From: Arad Carmi <62752352+AradCarmi@users.noreply.github.com> Date: Mon, 19 Feb 2024 16:53:23 +0200 Subject: [PATCH 025/272] XSIAM Compliance Dashboard&Report Update (#31947) * test commit * Update RN * Ignoring failing RN validation * Updated to verison 2.0.0 * Changed ReadME * Updated RN * Updated RN * Updated Hipaa RN testing * Updated RN * Updated README * Updated pack ignore --------- Co-authored-by: cweltPA <129675344+cweltPA@users.noreply.github.com> --- Packs/XSIAMCompliance_HIPAA/.pack-ignore | 11 ++++++++++- Packs/XSIAMCompliance_HIPAA/README.md | 6 ++---- Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_1.md | 7 +++++-- Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_2.md | 8 +++++--- Packs/XSIAMCompliance_HIPAA/ReleaseNotes/2_0_0.md | 12 ++++++++++++ Packs/XSIAMCompliance_HIPAA/pack_metadata.json | 10 ++++------ Packs/XSIAMCompliance_NIST_800_171/.pack-ignore | 11 ++++++++++- Packs/XSIAMCompliance_NIST_800_171/README.md | 4 +--- .../ReleaseNotes/1_0_1.md | 5 +++-- .../ReleaseNotes/1_0_2.md | 7 ++++--- .../ReleaseNotes/2_0_0.md | 12 ++++++++++++ .../XSIAMCompliance_NIST_800_171/pack_metadata.json | 10 ++++------ Packs/XSIAMCompliance_NIST_800_53/.pack-ignore | 11 ++++++++++- Packs/XSIAMCompliance_NIST_800_53/README.md | 4 +--- .../ReleaseNotes/1_0_1.md | 5 +++-- .../ReleaseNotes/1_0_2.md | 5 +++-- .../ReleaseNotes/2_0_0.md | 12 ++++++++++++ Packs/XSIAMCompliance_NIST_800_53/pack_metadata.json | 10 ++++------ Packs/XSIAMCompliance_NIST_CSF/.pack-ignore | 11 ++++++++++- Packs/XSIAMCompliance_NIST_CSF/README.md | 3 +-- Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_1.md | 5 +++-- Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_2.md | 7 ++++--- Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/2_0_0.md | 12 ++++++++++++ Packs/XSIAMCompliance_NIST_CSF/pack_metadata.json | 10 ++++------ Packs/XSIAMCompliance_PCI_DSS/.pack-ignore | 11 ++++++++++- Packs/XSIAMCompliance_PCI_DSS/README.md | 3 +-- Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_1.md | 5 +++-- Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_2.md | 7 ++++--- Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/2_0_0.md | 12 ++++++++++++ Packs/XSIAMCompliance_PCI_DSS/pack_metadata.json | 10 ++++------ Packs/XSIAMCompliance_SOX/.pack-ignore | 7 +++++++ Packs/XSIAMCompliance_SOX/README.md | 3 +-- Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_1.md | 5 +++-- Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_2.md | 7 ++++--- Packs/XSIAMCompliance_SOX/ReleaseNotes/2_0_0.md | 12 ++++++++++++ Packs/XSIAMCompliance_SOX/pack_metadata.json | 10 ++++------ 36 files changed, 204 insertions(+), 86 deletions(-) create mode 100644 Packs/XSIAMCompliance_HIPAA/ReleaseNotes/2_0_0.md create mode 100644 Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/2_0_0.md create mode 100644 Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/2_0_0.md create mode 100644 Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/2_0_0.md create mode 100644 Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/2_0_0.md create mode 100644 Packs/XSIAMCompliance_SOX/ReleaseNotes/2_0_0.md diff --git a/Packs/XSIAMCompliance_HIPAA/.pack-ignore b/Packs/XSIAMCompliance_HIPAA/.pack-ignore index 5ecb5bcafff9..3163d5595c00 100644 --- a/Packs/XSIAMCompliance_HIPAA/.pack-ignore +++ b/Packs/XSIAMCompliance_HIPAA/.pack-ignore @@ -1,2 +1,11 @@ [known_words] -HIPAA \ No newline at end of file +HIPAA + +[file:1_0_1.md] +ignore=RN113,RN114 + +[file:1_0_2.md] +ignore=RN113,RN114 + +[file:2_0_0.md] +ignore=RN113,RN114 \ No newline at end of file diff --git a/Packs/XSIAMCompliance_HIPAA/README.md b/Packs/XSIAMCompliance_HIPAA/README.md index c00a2469aef4..b503455450f4 100644 --- a/Packs/XSIAMCompliance_HIPAA/README.md +++ b/Packs/XSIAMCompliance_HIPAA/README.md @@ -1,6 +1,5 @@ -## **Generate Compliance Dashboard and Reports** -The HIPAA compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. The dashboard and report aggregate and reference all data mapped to the Cortex Data Model (XDM). - +## **Generate Compliance Dashboards and Reports** +The HIPAA compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. @@ -8,5 +7,4 @@ The HIPAA compliance pack provides a comprehensive dashboard and report template ## **What does this pack do?** - Install dashboard and report templates for the HIPAA regulations. -- Reference data that has been mapped to the Cortex Data Model (XDM). - Produce regulation evidence for audits. diff --git a/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_1.md b/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_1.md index 04117346a72b..3252eacb4779 100644 --- a/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_1.md +++ b/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_1.md @@ -1,4 +1,7 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### HIPAA Compliance Dashboard + - Note: The pack moved to closed source. + + diff --git a/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_2.md b/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_2.md index 2ad2a755b44c..314e63718ee9 100644 --- a/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_2.md +++ b/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/1_0_2.md @@ -1,5 +1,7 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### HIPAA Compliance Dashboard + - Added support for lazy loading the widgets. -- Added support for caching the widgets data. \ No newline at end of file +- Added support for caching the widgets data. + diff --git a/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/2_0_0.md b/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/2_0_0.md new file mode 100644 index 000000000000..d08b2b494fef --- /dev/null +++ b/Packs/XSIAMCompliance_HIPAA/ReleaseNotes/2_0_0.md @@ -0,0 +1,12 @@ +#### XSIAM Dashboards + +##### HIPAA Compliance Dashboard + +- Improved layout of the dashboard. +- Updated XQL queries to improve dashboard load times. + +#### XSIAM Reports + +##### HIPAA Compliance Report + +- Updated XQL queries to improve report load time. \ No newline at end of file diff --git a/Packs/XSIAMCompliance_HIPAA/pack_metadata.json b/Packs/XSIAMCompliance_HIPAA/pack_metadata.json index 4bfa3183afd9..2b8e37615c87 100644 --- a/Packs/XSIAMCompliance_HIPAA/pack_metadata.json +++ b/Packs/XSIAMCompliance_HIPAA/pack_metadata.json @@ -2,14 +2,13 @@ "name": "HIPAA Compliance", "description": "Ensure your organization is following HIPAA guidelines with the relevant dashboard and report evidence.", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "2.0.0", "author": "Cortex XSIAM", "url": "https://www.paloaltonetworks.com/cortex", "categories": [ "Analytics & SIEM" ], - "tags": [ - ], + "tags": [], "created": "2023-03-20T13:16:53Z", "useCases": [ "Compliance" @@ -21,7 +20,6 @@ "compliance" ], "marketplaces": [ - "marketplacev2" + "marketplacev2" ] - -} +} \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_800_171/.pack-ignore b/Packs/XSIAMCompliance_NIST_800_171/.pack-ignore index 480c57d975e5..3041bee4654d 100644 --- a/Packs/XSIAMCompliance_NIST_800_171/.pack-ignore +++ b/Packs/XSIAMCompliance_NIST_800_171/.pack-ignore @@ -1,2 +1,11 @@ [known_words] -NIST \ No newline at end of file +NIST + +[file:1_0_1.md] +ignore=RN113,RN114 + +[file:1_0_2.md] +ignore=RN113,RN114 + +[file:2_0_0.md] +ignore=RN113,RN114 \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_800_171/README.md b/Packs/XSIAMCompliance_NIST_800_171/README.md index daf2d755ea2f..e3d4c2a4390a 100644 --- a/Packs/XSIAMCompliance_NIST_800_171/README.md +++ b/Packs/XSIAMCompliance_NIST_800_171/README.md @@ -1,10 +1,8 @@ ## **Generate Compliance Dashboards and Reports** -The NIST 800-171 compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. The dashboard and report aggregate and reference all data mapped to the Cortex Data Model (XDM). - +The NIST 800-171 compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. **Note:** This pack is currently offered as a free beta of the Compliance module for a limited time. In the future, this module will be sold separately on top of XSIAM. ## **What does this pack do?** - Install dashboard and report templates for the NIST 800-171 regulations. -- Reference data that has been mapped to the Cortex Data Model (XDM). - Produce regulation evidence for audits. diff --git a/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/1_0_1.md b/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/1_0_1.md index 04117346a72b..75a5ad905e85 100644 --- a/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/1_0_1.md +++ b/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/1_0_1.md @@ -1,4 +1,5 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### NIST 800-171 Compliance Dashboard + - Note: The pack moved to closed source. diff --git a/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/1_0_2.md b/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/1_0_2.md index 2ad2a755b44c..acae386c0d46 100644 --- a/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/1_0_2.md +++ b/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/1_0_2.md @@ -1,5 +1,6 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### NIST 800-171 Compliance Dashboard + - Added support for lazy loading the widgets. -- Added support for caching the widgets data. \ No newline at end of file +- Added support for caching the widgets data. diff --git a/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/2_0_0.md b/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/2_0_0.md new file mode 100644 index 000000000000..89e891ca8e31 --- /dev/null +++ b/Packs/XSIAMCompliance_NIST_800_171/ReleaseNotes/2_0_0.md @@ -0,0 +1,12 @@ +#### XSIAM Dashboards + +##### NIST 800-171 Compliance Dashboard + +- Improved layout of the dashboard. +- Updated XQL queries to improve dashboard load times. + +#### XSIAM Reports + +##### NIST 800-171 Compliance Report + +- Updated XQL queries to improve report load time. \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_800_171/pack_metadata.json b/Packs/XSIAMCompliance_NIST_800_171/pack_metadata.json index 6908241d1568..4a7b6b6a5e98 100644 --- a/Packs/XSIAMCompliance_NIST_800_171/pack_metadata.json +++ b/Packs/XSIAMCompliance_NIST_800_171/pack_metadata.json @@ -2,14 +2,13 @@ "name": "NIST 800-171 Compliance", "description": "Ensure your organization is following NIST 800-171 guidelines with the relevant dashboard and report evidence.", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "2.0.0", "author": "Cortex XSIAM", "url": "https://www.paloaltonetworks.com/cortex", "categories": [ "Analytics & SIEM" ], - "tags": [ - ], + "tags": [], "created": "2023-03-20T13:16:53Z", "useCases": [ "Compliance" @@ -21,7 +20,6 @@ "compliance" ], "marketplaces": [ - "marketplacev2" + "marketplacev2" ] - -} +} \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_800_53/.pack-ignore b/Packs/XSIAMCompliance_NIST_800_53/.pack-ignore index 480c57d975e5..3041bee4654d 100644 --- a/Packs/XSIAMCompliance_NIST_800_53/.pack-ignore +++ b/Packs/XSIAMCompliance_NIST_800_53/.pack-ignore @@ -1,2 +1,11 @@ [known_words] -NIST \ No newline at end of file +NIST + +[file:1_0_1.md] +ignore=RN113,RN114 + +[file:1_0_2.md] +ignore=RN113,RN114 + +[file:2_0_0.md] +ignore=RN113,RN114 \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_800_53/README.md b/Packs/XSIAMCompliance_NIST_800_53/README.md index fa4208533e91..68db1e19eebc 100644 --- a/Packs/XSIAMCompliance_NIST_800_53/README.md +++ b/Packs/XSIAMCompliance_NIST_800_53/README.md @@ -1,11 +1,9 @@ ## **Generate Compliance Dashboards and Reports** -The NIST 800-53 compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. The dashboard and report aggregate and reference all data mapped to the Cortex Data Model (XDM). - +The NIST 800-53 compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. **Note:** This pack is currently offered as a free beta of the Compliance module for a limited time. In the future, this module will be sold separately on top of XSIAM. ## **What does this pack do?** - Install dashboard and report templates for the NIST 800-53 regulations. -- Reference data that has been mapped to the Cortex Data Model (XDM). - Produce regulation evidence for audits. diff --git a/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/1_0_1.md b/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/1_0_1.md index 04117346a72b..f6065039825d 100644 --- a/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/1_0_1.md +++ b/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/1_0_1.md @@ -1,4 +1,5 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### NIST 800-53 Compliance Dashboard + - Note: The pack moved to closed source. diff --git a/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/1_0_2.md b/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/1_0_2.md index 2ad2a755b44c..657a70f394a6 100644 --- a/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/1_0_2.md +++ b/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/1_0_2.md @@ -1,5 +1,6 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### NIST 800-53 Compliance Dashboard + - Added support for lazy loading the widgets. - Added support for caching the widgets data. \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/2_0_0.md b/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/2_0_0.md new file mode 100644 index 000000000000..99c4da913928 --- /dev/null +++ b/Packs/XSIAMCompliance_NIST_800_53/ReleaseNotes/2_0_0.md @@ -0,0 +1,12 @@ +#### XSIAM Dashboards + +##### NIST 800-53 Compliance Dashboard + +- Improved layout of the dashboard. +- Updated XQL queries to improve dashboard load times. + +#### XSIAM Reports + +##### NIST 800-53 Compliance Report + +- Updated XQL queries to improve report load time. \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_800_53/pack_metadata.json b/Packs/XSIAMCompliance_NIST_800_53/pack_metadata.json index ce810eb95c78..a7c01f82d5a5 100644 --- a/Packs/XSIAMCompliance_NIST_800_53/pack_metadata.json +++ b/Packs/XSIAMCompliance_NIST_800_53/pack_metadata.json @@ -2,14 +2,13 @@ "name": "NIST 800-53 Compliance", "description": "Ensure your organization is following NIST 800-53 guidelines with the relevant dashboard and report evidence.", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "2.0.0", "author": "Cortex XSIAM", "url": "https://www.paloaltonetworks.com/cortex", "categories": [ "Analytics & SIEM" ], - "tags": [ - ], + "tags": [], "created": "2023-03-20T13:16:53Z", "useCases": [ "Compliance" @@ -21,7 +20,6 @@ "compliance" ], "marketplaces": [ - "marketplacev2" + "marketplacev2" ] - -} +} \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_CSF/.pack-ignore b/Packs/XSIAMCompliance_NIST_CSF/.pack-ignore index 5497e233e5f4..20db28a97d1d 100644 --- a/Packs/XSIAMCompliance_NIST_CSF/.pack-ignore +++ b/Packs/XSIAMCompliance_NIST_CSF/.pack-ignore @@ -1,3 +1,12 @@ [known_words] NIST -CSF \ No newline at end of file +CSF + +[file:1_0_1.md] +ignore=RN113,RN114 + +[file:1_0_2.md] +ignore=RN113,RN114 + +[file:2_0_0.md] +ignore=RN113,RN114 \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_CSF/README.md b/Packs/XSIAMCompliance_NIST_CSF/README.md index 4d20a8dddd42..4013d1c3f616 100644 --- a/Packs/XSIAMCompliance_NIST_CSF/README.md +++ b/Packs/XSIAMCompliance_NIST_CSF/README.md @@ -1,10 +1,9 @@ ## **Generate Compliance Dashboards and Reports** -The NIST CSF compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. The dashboard and report aggregate and reference all data mapped to the Cortex Data Model (XDM). +The NIST CSF compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. **Note:** This pack is currently offered as a free beta of the Compliance module for a limited time. In the future, this module will be sold separately on top of XSIAM. ## **What does this pack do?** - Install dashboard and report templates for the NIST CSF regulations. -- Reference data that has been mapped to the Cortex Data Model (XDM). - Produce regulation evidence for audits. diff --git a/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_1.md b/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_1.md index 04117346a72b..325e2955c82b 100644 --- a/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_1.md +++ b/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_1.md @@ -1,4 +1,5 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### NIST CSF Compliance Dashboard + - Note: The pack moved to closed source. diff --git a/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_2.md b/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_2.md index 2ad2a755b44c..39054fd4f057 100644 --- a/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_2.md +++ b/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/1_0_2.md @@ -1,5 +1,6 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### NIST CSF Compliance Dashboard + - Added support for lazy loading the widgets. -- Added support for caching the widgets data. \ No newline at end of file +- Added support for caching the widgets data. diff --git a/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/2_0_0.md b/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/2_0_0.md new file mode 100644 index 000000000000..c54f9b199b3f --- /dev/null +++ b/Packs/XSIAMCompliance_NIST_CSF/ReleaseNotes/2_0_0.md @@ -0,0 +1,12 @@ +#### XSIAM Dashboards + +##### NIST CSF Compliance Dashboard + +- Improved layout of the dashboard. +- Updated XQL queries to improve dashboard load times. + +#### XSIAM Reports + +##### NIST CSF Compliance Report + +- Updated XQL queries to improve report load time. \ No newline at end of file diff --git a/Packs/XSIAMCompliance_NIST_CSF/pack_metadata.json b/Packs/XSIAMCompliance_NIST_CSF/pack_metadata.json index c862ffd688c4..daf5bbf5b653 100644 --- a/Packs/XSIAMCompliance_NIST_CSF/pack_metadata.json +++ b/Packs/XSIAMCompliance_NIST_CSF/pack_metadata.json @@ -2,14 +2,13 @@ "name": "NIST CSF Compliance", "description": "Ensure your organization is following NIST CSF guidelines with the relevant dashboard and report evidence.", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "2.0.0", "author": "Cortex XSIAM", "url": "https://www.paloaltonetworks.com/cortex", "categories": [ "Analytics & SIEM" ], - "tags": [ - ], + "tags": [], "created": "2023-03-20T13:16:53Z", "useCases": [ "Compliance" @@ -21,7 +20,6 @@ "compliance" ], "marketplaces": [ - "marketplacev2" + "marketplacev2" ] - -} +} \ No newline at end of file diff --git a/Packs/XSIAMCompliance_PCI_DSS/.pack-ignore b/Packs/XSIAMCompliance_PCI_DSS/.pack-ignore index 6a492984e0af..93ac88c1c0c6 100644 --- a/Packs/XSIAMCompliance_PCI_DSS/.pack-ignore +++ b/Packs/XSIAMCompliance_PCI_DSS/.pack-ignore @@ -1,3 +1,12 @@ [known_words] PCI -DSS \ No newline at end of file +DSS + +[file:1_0_1.md] +ignore=RN113,RN114 + +[file:1_0_2.md] +ignore=RN113,RN114 + +[file:2_0_0.md] +ignore=RN113,RN114 \ No newline at end of file diff --git a/Packs/XSIAMCompliance_PCI_DSS/README.md b/Packs/XSIAMCompliance_PCI_DSS/README.md index 0e28a706b7d1..e20a9530ac54 100644 --- a/Packs/XSIAMCompliance_PCI_DSS/README.md +++ b/Packs/XSIAMCompliance_PCI_DSS/README.md @@ -1,9 +1,8 @@ ## **Generate Compliance Dashboards and Reports** -The PCI DSS compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. The dashboard and report aggregate and reference all data mapped to the Cortex Data Model (XDM). +The PCI DSS compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. **Note:** This pack is currently offered as a free beta of the Compliance module for a limited time. In the future, this module will be sold separately on top of XSIAM. ## **What does this pack do?** - Install dashboard and report templates for the PCI DSS regulations. -- Reference data that has been mapped to the Cortex Data Model (XDM). - Produce regulation evidence for audits. diff --git a/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_1.md b/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_1.md index 04117346a72b..ef990bfc6360 100644 --- a/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_1.md +++ b/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_1.md @@ -1,4 +1,5 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### PCI DSS Compliance Dashboard + - Note: The pack moved to closed source. diff --git a/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_2.md b/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_2.md index 2ad2a755b44c..b86b8fb54083 100644 --- a/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_2.md +++ b/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/1_0_2.md @@ -1,5 +1,6 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### PCI DSS Compliance Dashboard + - Added support for lazy loading the widgets. -- Added support for caching the widgets data. \ No newline at end of file +- Added support for caching the widgets data. diff --git a/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/2_0_0.md b/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/2_0_0.md new file mode 100644 index 000000000000..a16c9334e3a2 --- /dev/null +++ b/Packs/XSIAMCompliance_PCI_DSS/ReleaseNotes/2_0_0.md @@ -0,0 +1,12 @@ +#### XSIAM Dashboards + +##### PCI DSS Compliance Dashboard + +- Improved layout of the dashboard. +- Updated XQL queries to improve dashboard load times. + +#### XSIAM Reports + +##### PCI DSS Compliance Report + +- Updated XQL queries to improve report load time. \ No newline at end of file diff --git a/Packs/XSIAMCompliance_PCI_DSS/pack_metadata.json b/Packs/XSIAMCompliance_PCI_DSS/pack_metadata.json index 2728e8f6bbc0..74388402b982 100644 --- a/Packs/XSIAMCompliance_PCI_DSS/pack_metadata.json +++ b/Packs/XSIAMCompliance_PCI_DSS/pack_metadata.json @@ -2,14 +2,13 @@ "name": "PCI DSS Compliance", "description": "Ensure your organization is following PCI DSS guidelines with the relevant dashboard and report evidence.", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "2.0.0", "author": "Cortex XSIAM", "url": "https://www.paloaltonetworks.com/cortex", "categories": [ "Analytics & SIEM" ], - "tags": [ - ], + "tags": [], "created": "2023-03-20T13:16:53Z", "useCases": [ "Compliance" @@ -21,7 +20,6 @@ "compliance" ], "marketplaces": [ - "marketplacev2" + "marketplacev2" ] - -} +} \ No newline at end of file diff --git a/Packs/XSIAMCompliance_SOX/.pack-ignore b/Packs/XSIAMCompliance_SOX/.pack-ignore index 8b137891791f..5fc5c37c39d5 100644 --- a/Packs/XSIAMCompliance_SOX/.pack-ignore +++ b/Packs/XSIAMCompliance_SOX/.pack-ignore @@ -1 +1,8 @@ +[file:1_0_1.md] +ignore=RN113,RN114 +[file:1_0_2.md] +ignore=RN113,RN114 + +[file:2_0_0.md] +ignore=RN113,RN114 \ No newline at end of file diff --git a/Packs/XSIAMCompliance_SOX/README.md b/Packs/XSIAMCompliance_SOX/README.md index 303ee0d5eae8..39e2ccdd16e7 100644 --- a/Packs/XSIAMCompliance_SOX/README.md +++ b/Packs/XSIAMCompliance_SOX/README.md @@ -1,10 +1,9 @@ ## **Generate Compliance Dashboards and Reports** -The SOX compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. The dashboard and report aggregate and reference all data mapped to the Cortex Data Model (XDM). +The SOX compliance pack provides a comprehensive dashboard and report template to easily monitor your Cortex XSIAM data compliance regulations and provide evidence for compliance audits. **Note:** This pack is currently offered as a free beta of the Compliance module for a limited time. In the future, this module will be sold separately on top of XSIAM. ## **What does this pack do?** - Install dashboard and report templates for the SOX regulations. -- Reference data that has been mapped to the Cortex Data Model (XDM). - Produce regulation evidence for audits. diff --git a/Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_1.md b/Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_1.md index 04117346a72b..285ecfc9c132 100644 --- a/Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_1.md +++ b/Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_1.md @@ -1,4 +1,5 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### SOX Compliance Dashboard + - Note: The pack moved to closed source. diff --git a/Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_2.md b/Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_2.md index 2ad2a755b44c..963234bbed78 100644 --- a/Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_2.md +++ b/Packs/XSIAMCompliance_SOX/ReleaseNotes/1_0_2.md @@ -1,5 +1,6 @@ - #### XSIAM Dashboards -##### XSIAMCompliance_HIPAA_Dashboard + +##### SOX Compliance Dashboard + - Added support for lazy loading the widgets. -- Added support for caching the widgets data. \ No newline at end of file +- Added support for caching the widgets data. diff --git a/Packs/XSIAMCompliance_SOX/ReleaseNotes/2_0_0.md b/Packs/XSIAMCompliance_SOX/ReleaseNotes/2_0_0.md new file mode 100644 index 000000000000..a008d77b2132 --- /dev/null +++ b/Packs/XSIAMCompliance_SOX/ReleaseNotes/2_0_0.md @@ -0,0 +1,12 @@ +#### XSIAM Dashboards + +##### SOX Compliance Dashboard + +- Improved layout of the dashboard. +- Updated XQL queries to improve dashboard load times. + +#### XSIAM Reports + +##### SOX Compliance Report + +- Updated XQL queries to improve report load time. \ No newline at end of file diff --git a/Packs/XSIAMCompliance_SOX/pack_metadata.json b/Packs/XSIAMCompliance_SOX/pack_metadata.json index 9db1363896ae..2455566b30d4 100644 --- a/Packs/XSIAMCompliance_SOX/pack_metadata.json +++ b/Packs/XSIAMCompliance_SOX/pack_metadata.json @@ -2,14 +2,13 @@ "name": "SOX Compliance", "description": "Ensure your organization is following SOX guidelines with the relevant dashboard and report evidence.", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "2.0.0", "author": "Cortex XSIAM", "url": "https://www.paloaltonetworks.com/cortex", "categories": [ "Analytics & SIEM" ], - "tags": [ - ], + "tags": [], "created": "2023-03-20T13:16:53Z", "useCases": [ "Compliance" @@ -21,7 +20,6 @@ "compliance" ], "marketplaces": [ - "marketplacev2" + "marketplacev2" ] - -} +} \ No newline at end of file From 425775f6729825202d93c307502c68eb00624800 Mon Sep 17 00:00:00 2001 From: Adi Daud <46249224+adi88d@users.noreply.github.com> Date: Mon, 19 Feb 2024 22:50:36 +0200 Subject: [PATCH 026/272] PhishTank v2 - Added the username parameter (#32951) * added the username parameter * update docker * set username as optional * doc review * add test_user_agent_header * flake8 --- .../Integrations/PhishTankV2/PhishTankV2.py | 12 ++++++++-- .../Integrations/PhishTankV2/PhishTankV2.yml | 5 +++- .../PhishTankV2/PhishTankV2_test.py | 24 +++++++++++++++++-- Packs/PhishTank/ReleaseNotes/2_0_30.md | 4 ++++ Packs/PhishTank/pack_metadata.json | 2 +- 5 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 Packs/PhishTank/ReleaseNotes/2_0_30.md diff --git a/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2.py b/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2.py index ce548a66c622..6ab9ff78b225 100644 --- a/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2.py +++ b/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2.py @@ -35,19 +35,26 @@ class Client(BaseClient): use_https (bool): Whether to use HTTPS URL or HTTP URL. """ - def __init__(self, proxy: bool, verify: bool, fetch_interval_hours: str, use_https: str, reliability: str): + def __init__(self, proxy: bool, verify: bool, fetch_interval_hours: str, use_https: str, reliability: str, + username: str = ''): super().__init__(proxy=proxy, verify=verify, base_url=HTTPS_BASE_URL if use_https else BASE_URL) self.fetch_interval_hours = fetch_interval_hours + self.username = username + if DBotScoreReliability.is_valid_type(reliability): self.reliability = DBotScoreReliability.get_dbot_score_reliability_from_str(reliability) else: return_error("PhishTankV2 error: Please provide a valid value for the Source Reliability parameter.") def get_http_request(self, url_suffix: str): + headers = {} + if self.username: + headers = {'User-Agent': f'phishtank/{self.username}'} result = self._http_request( method='GET', url_suffix=url_suffix, resp_type="text", + headers=headers, error_handler=handle_error ) return result @@ -316,13 +323,14 @@ def main() -> None: verify = not params.get('insecure') fetch_interval_hours = params.get('fetchIntervalHours') reliability = params.get('integrationReliability') + username = params.get('username') if not is_number(fetch_interval_hours): return_error("PhishTankV2 error: Please provide a numeric value (and bigger than 0) for Database refresh " "interval (hours)") # initialize a client - client = Client(proxy, verify, fetch_interval_hours, use_https, reliability) + client = Client(proxy, verify, fetch_interval_hours, use_https, reliability, username) command = demisto.command() demisto.debug(f'PhishTankV2: command is {command}') diff --git a/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2.yml b/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2.yml index 0dee64c88ad5..f07f3ec3d33c 100644 --- a/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2.yml +++ b/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2.yml @@ -3,6 +3,9 @@ commonfields: id: PhishTank V2 version: -1 configuration: +- display: Username + name: username + type: 0 - defaultvalue: 'false' display: Use HTTPS connection name: use_https @@ -78,7 +81,7 @@ script: name: phishtank-reload - description: Shows the status (timestamp) of the last time that PhishTank database was loaded. name: phishtank-status - dockerimage: demisto/python3:3.10.13.73190 + dockerimage: demisto/python3:3.10.13.87159 runonce: false script: '-' subtype: python3 diff --git a/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2_test.py b/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2_test.py index 441f99ca6bb5..d60969578281 100644 --- a/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2_test.py +++ b/Packs/PhishTank/Integrations/PhishTankV2/PhishTankV2_test.py @@ -10,9 +10,9 @@ def create_client(proxy: bool = False, verify: bool = False, fetch_interval_hours: str = "1", - reliability: str = DBotScoreReliability.A_PLUS): + reliability: str = DBotScoreReliability.A_PLUS, username: str = ''): return Client(proxy=proxy, verify=verify, fetch_interval_hours=fetch_interval_hours, use_https=False, - reliability=reliability) + reliability=reliability, username=username) @pytest.mark.parametrize('number, output', [("True", False), ('432', True), ("str", False), @@ -243,3 +243,23 @@ def test_url_command(mocker, data, url, expected_score, expected_table): # validate human readable hr_ = command_results[0].to_context().get('HumanReadable', {}) assert hr_ == expected_table + + +@pytest.mark.parametrize('username, expected_headers', [ + ('test', {'User-Agent': 'phishtank/test'}), + ('', {})]) +def test_user_agent_header(mocker, username, expected_headers): + """ + Given: + - phishtank username + + When: + - After reload or url command + + Then: + - validating that the User-Agent header is populated as expected + """ + http_request = mocker.patch.object(Client, "_http_request", return_value='') + client = create_client(False, False, "1", DBotScoreReliability.B, username) + reload(client) + assert http_request.call_args.kwargs['headers'] == expected_headers diff --git a/Packs/PhishTank/ReleaseNotes/2_0_30.md b/Packs/PhishTank/ReleaseNotes/2_0_30.md new file mode 100644 index 000000000000..509d1527f406 --- /dev/null +++ b/Packs/PhishTank/ReleaseNotes/2_0_30.md @@ -0,0 +1,4 @@ +#### Integrations +##### PhishTank v2 +- Added a new parameter *username*. Allows adding the PhishTank user to the requests header in order to increase the rate limit. +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. \ No newline at end of file diff --git a/Packs/PhishTank/pack_metadata.json b/Packs/PhishTank/pack_metadata.json index 3a22155cbba4..eab9df634856 100644 --- a/Packs/PhishTank/pack_metadata.json +++ b/Packs/PhishTank/pack_metadata.json @@ -2,7 +2,7 @@ "name": "PhishTank", "description": "PhishTank is a free community site where anyone can submit, verify, track and share phishing data", "support": "xsoar", - "currentVersion": "2.0.29", + "currentVersion": "2.0.30", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From f792bfcb4b25d1cf05bf389393483e4f9d4e96c0 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Tue, 20 Feb 2024 02:53:39 +0200 Subject: [PATCH 027/272] [CortexXpanse] Update Integration Fetch Offset (#32868) (#33002) * Remove 3 second offset * Add debug logging and remove comments * changes after convo with John * docket and RN * bump ver * edit RN * readd old RN * Update Packs/CortexXpanse/Integrations/CortexXpanse/CortexXpanse.py --------- Co-authored-by: johnnywilkes <32227961+johnnywilkes@users.noreply.github.com> Co-authored-by: bigeasyj Co-authored-by: John <40349459+BigEasyJ@users.noreply.github.com> Co-authored-by: Moshe Galitzky <112559840+moishce@users.noreply.github.com> --- .../Integrations/CortexXpanse/CortexXpanse.py | 19 ++++++++++++++----- Packs/CortexXpanse/ReleaseNotes/1_0_19.md | 3 +++ Packs/CortexXpanse/pack_metadata.json | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 Packs/CortexXpanse/ReleaseNotes/1_0_19.md diff --git a/Packs/CortexXpanse/Integrations/CortexXpanse/CortexXpanse.py b/Packs/CortexXpanse/Integrations/CortexXpanse/CortexXpanse.py index dab56bcfb32f..6dee0708b5f7 100644 --- a/Packs/CortexXpanse/Integrations/CortexXpanse/CortexXpanse.py +++ b/Packs/CortexXpanse/Integrations/CortexXpanse/CortexXpanse.py @@ -9,7 +9,6 @@ DEFAULT_SEARCH_LIMIT = 100 MAX_ALERTS = 100 # max alerts per fetch -ONE_HOUR = 3600 TIME_FORMAT = "%Y-%m-%dT%H:%M:%S" V1_URL_SUFFIX = "/public_api/v1" V2_URL_SUFFIX = "/public_api/v2" @@ -1290,11 +1289,9 @@ def fetch_incidents(client: Client, max_fetch: int, last_run: dict[str, int], # Handle first time fetch last_fetch = first_fetch_time if last_fetch is None else int(last_fetch) - latest_created_time = cast(int, last_fetch) - # because some values are not populated immediately at alert creation time, - # we will add an additional offset to increase the likelihood that these are available - latest_created_time = latest_created_time + ONE_HOUR + + demisto.debug(f"CortexXpanse - last fetched alert timestamp: {str(last_fetch)}") incidents = [] @@ -1330,6 +1327,10 @@ def fetch_incidents(client: Client, max_fetch: int, last_run: dict[str, int], latest_created_time = incident_created_time next_run = {'last_fetch': latest_created_time} + + demisto.debug(f"CortexXpanse - Number of incidents: {len(incidents)}") + demisto.debug(f"CortexXpanse - Next run after incidents fetching: : {next_run}") + return next_run, incidents @@ -1416,6 +1417,14 @@ def main() -> None: headers=headers, proxy=proxy) + # To debug integration instance configuration. + integration_context = demisto.getIntegrationContext() + if 'xpanse_integration_severity' in integration_context: + xpanse_integration_severity = integration_context.get('xpanse_integration_severity') + if xpanse_integration_severity != severity: + demisto.setIntegrationContext({"xpanse_integration_severity": severity}) + demisto.debug(demisto.debug(f"CortexXpanse - Integration Severity: {severity}")) + commands = { 'asm-list-external-service': list_external_service_command, 'asm-get-external-service': get_external_service_command, diff --git a/Packs/CortexXpanse/ReleaseNotes/1_0_19.md b/Packs/CortexXpanse/ReleaseNotes/1_0_19.md new file mode 100644 index 000000000000..589524adfc01 --- /dev/null +++ b/Packs/CortexXpanse/ReleaseNotes/1_0_19.md @@ -0,0 +1,3 @@ +#### Integrations +##### Cortex Xpanse +Updated the fetch logic to no longer contain a one hour offset. diff --git a/Packs/CortexXpanse/pack_metadata.json b/Packs/CortexXpanse/pack_metadata.json index 4b1bf85a265a..c9a700d8355b 100644 --- a/Packs/CortexXpanse/pack_metadata.json +++ b/Packs/CortexXpanse/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cortex Xpanse", "description": "Content for working with Attack Surface Management (ASM).", "support": "xsoar", - "currentVersion": "1.0.18", + "currentVersion": "1.0.19", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From adaba25b71ad61c1a4f1c5b278f75ef21d73025f Mon Sep 17 00:00:00 2001 From: Dan Tavori <38749041+dantavori@users.noreply.github.com> Date: Tue, 20 Feb 2024 07:10:27 +0200 Subject: [PATCH 028/272] metrics in csp (#32383) --- Packs/Base/ReleaseNotes/1_33_33.md | 6 + .../CommonServerPython/CommonServerPython.py | 201 +++++++++++++--- .../CommonServerPython_test.py | 221 ++++++++++++++++++ Packs/Base/pack_metadata.json | 2 +- .../Integrations/EmailHippo/EmailHippo.py | 51 ++-- .../EmailHippo/EmailHippo_test.py | 54 ++++- Packs/EmailHippo/ReleaseNotes/1_0_4.md | 6 + Packs/EmailHippo/pack_metadata.json | 2 +- 8 files changed, 479 insertions(+), 64 deletions(-) create mode 100644 Packs/Base/ReleaseNotes/1_33_33.md create mode 100644 Packs/EmailHippo/ReleaseNotes/1_0_4.md diff --git a/Packs/Base/ReleaseNotes/1_33_33.md b/Packs/Base/ReleaseNotes/1_33_33.md new file mode 100644 index 000000000000..f9cfc0c1bc55 --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_33_33.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### CommonServerPython + +- Added support for execution metrics in the *BaseClient* class. diff --git a/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py b/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py index e44e32aff057..fc52b1e430d5 100644 --- a/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py +++ b/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py @@ -199,7 +199,7 @@ def __del__(self): import requests from requests.adapters import HTTPAdapter from urllib3.util import Retry - from typing import Optional, Dict, List, Any, Union, Set + from typing import Optional, Dict, List, Any, Union, Set, cast from urllib3 import disable_warnings disable_warnings() @@ -512,6 +512,7 @@ class ErrorTypes(object): PROXY_ERROR = 'ProxyError' SSL_ERROR = 'SSLError' TIMEOUT_ERROR = 'TimeoutError' + RETRY_ERROR = "RetryError" class FeedIndicatorType(object): @@ -7322,7 +7323,7 @@ class ExecutionMetrics(object): """ def __init__(self, success=0, quota_error=0, general_error=0, auth_error=0, service_error=0, connection_error=0, - proxy_error=0, ssl_error=0, timeout_error=0): + proxy_error=0, ssl_error=0, timeout_error=0, retry_error=0): self._metrics = [] self.metrics = None self.success = success @@ -7334,6 +7335,7 @@ def __init__(self, success=0, quota_error=0, general_error=0, auth_error=0, serv self.proxy_error = proxy_error self.ssl_error = ssl_error self.timeout_error = timeout_error + self.retry_error = retry_error """ Initializes an ExecutionMetrics object. Once initialized, you may increment each metric type according to the metric you'd like to report. Afterwards, pass the `metrics` value to CommandResults. @@ -7365,6 +7367,9 @@ def __init__(self, success=0, quota_error=0, general_error=0, auth_error=0, serv :type timeout_error: ``int`` :param timeout_error: Quantity of Timeout Error metrics + :type retry_error: ``int`` + :param retry_error: Quantity of Retry Error metrics + :type metrics: ``CommandResults`` :param metrics: Append this value to your CommandResults list to report the metrics to your server. """ @@ -7456,6 +7461,15 @@ def timeout_error(self, value): self._timeout_error = value self.update_metrics(ErrorTypes.TIMEOUT_ERROR, self._timeout_error) + @property + def retry_error(self): + return self._retry_error + + @retry_error.setter + def retry_error(self, value): + self._retry_error = value + self.update_metrics(ErrorTypes.RETRY_ERROR, self._retry_error) + def get_metric_list(self): return self._metrics @@ -8772,7 +8786,10 @@ def __init__( system_timeout = os.getenv('REQUESTS_TIMEOUT', '') self.timeout = float(entity_timeout or system_timeout or timeout) + self.execution_metrics = ExecutionMetrics() + def __del__(self): + self._return_execution_metrics_results() try: self._session.close() except AttributeError: @@ -8862,7 +8879,8 @@ def _http_request(self, method, url_suffix='', full_url=None, headers=None, auth params=None, data=None, files=None, timeout=None, resp_type='json', ok_codes=None, return_empty_response=False, retries=0, status_list_to_retry=None, backoff_factor=5, raise_on_redirect=False, raise_on_status=False, - error_handler=None, empty_valid_codes=None, params_parser=None, **kwargs): + error_handler=None, empty_valid_codes=None, params_parser=None, with_metrics=False, + **kwargs): """A wrapper for requests lib to send our requests and handle requests and responses better. :type method: ``str`` @@ -8960,6 +8978,9 @@ def _http_request(self, method, url_suffix='', full_url=None, headers=None, auth see here for more info: https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode Note! supported only in python3. + :type with_metrics ``bool`` + :param with_metrics: Whether or not to calculate execution metrics from the response + :return: Depends on the resp_type parameter :rtype: ``dict`` or ``str`` or ``bytes`` or ``xml.etree.ElementTree.Element`` or ``requests.Response`` """ @@ -8989,40 +9010,20 @@ def _http_request(self, method, url_suffix='', full_url=None, headers=None, auth timeout=timeout, **kwargs ) - # Handle error responses gracefully if not self._is_status_code_valid(res, ok_codes): - if error_handler: - error_handler(res) - else: - self.client_error_handler(res) + self._handle_error(error_handler, res, with_metrics) - if not empty_valid_codes: - empty_valid_codes = [204] - is_response_empty_and_successful = (res.status_code in empty_valid_codes) - if is_response_empty_and_successful and return_empty_response: - return res + return self._handle_success(res, resp_type, empty_valid_codes, return_empty_response, with_metrics) - resp_type = resp_type.lower() - try: - if resp_type == 'json': - return res.json() - if resp_type == 'text': - return res.text - if resp_type == 'content': - return res.content - if resp_type == 'xml': - ET.fromstring(res.text) - if resp_type == 'response': - return res - return res - except ValueError as exception: - raise DemistoException('Failed to parse {} object from response: {}' # type: ignore[str-bytes-safe] - .format(resp_type, res.content), exception, res) except requests.exceptions.ConnectTimeout as exception: + if with_metrics: + self.execution_metrics.timeout_error += 1 err_msg = 'Connection Timeout Error - potential reasons might be that the Server URL parameter' \ ' is incorrect or that the Server is not accessible from your host.' raise DemistoException(err_msg, exception) except requests.exceptions.SSLError as exception: + if with_metrics: + self.execution_metrics.ssl_error += 1 # in case the "Trust any certificate" is already checked if not self._verify: raise @@ -9030,10 +9031,14 @@ def _http_request(self, method, url_suffix='', full_url=None, headers=None, auth ' the integration configuration.' raise DemistoException(err_msg, exception) except requests.exceptions.ProxyError as exception: + if with_metrics: + self.execution_metrics.proxy_error += 1 err_msg = 'Proxy Error - if the \'Use system proxy\' checkbox in the integration configuration is' \ ' selected, try clearing the checkbox.' raise DemistoException(err_msg, exception) except requests.exceptions.ConnectionError as exception: + if with_metrics: + self.execution_metrics.connection_error += 1 # Get originating Exception in Exception chain error_class = str(exception.__class__) err_type = '<' + error_class[error_class.find('\'') + 1: error_class.rfind('\'')] + '>' @@ -9043,6 +9048,8 @@ def _http_request(self, method, url_suffix='', full_url=None, headers=None, auth .format(err_type, exception.errno, exception.strerror) raise DemistoException(err_msg, exception) except requests.exceptions.RetryError as exception: + if with_metrics: + self.execution_metrics.retry_error += 1 try: reason = 'Reason: {}'.format(exception.args[0].reason.args[0]) except Exception: # noqa: disable=broad-except @@ -9050,6 +9057,136 @@ def _http_request(self, method, url_suffix='', full_url=None, headers=None, auth err_msg = 'Max Retries Error- Request attempts with {} retries failed. \n{}'.format(retries, reason) raise DemistoException(err_msg, exception) + def _handle_error(self, error_handler, res, should_update_metrics): + """ Handles error response by calling error handler or default handler. + If an exception is raised, update metrics with failure. Otherwise, proceeds. + + :type res: ``requests.Response`` + :param res: Response from API after the request for which to check error type + + :type error_handler ``callable`` + :param error_handler: Given an error entry, the error handler outputs the + new formatted error message. + + :type should_update_metrics ``bool`` + :param should_update_metrics: Whether or not to update execution metrics according to response + """ + try: + if error_handler: + error_handler(res) + else: + self.client_error_handler(res) + except Exception: + if should_update_metrics: + self._update_metrics(res, success=False) + raise + + def _handle_success(self, res, resp_type, empty_valid_codes, return_empty_response, should_update_metrics): + """ Handles successful response + + :type res: ``requests.Response`` + :param res: Response from API after the request for which to check error type + + :type resp_type: ``str`` + :param resp_type: + Determines which data format to return from the HTTP request. The default + is 'json'. Other options are 'text', 'content', 'xml' or 'response'. Use 'response' + to return the full response object. + + :type empty_valid_codes: ``list`` + :param empty_valid_codes: A list of all valid status codes of empty responses (usually only 204, but + can vary) + + :type return_empty_response: ``bool`` + :param response: Whether to return an empty response body if the response code is in empty_valid_codes + + :type should_update_metrics ``bool`` + :param should_update_metrics: Whether or not to update execution metrics according to response + """ + if should_update_metrics: + self._update_metrics(res, success=True) + + if not empty_valid_codes: + empty_valid_codes = [204] + is_response_empty_and_successful = (res.status_code in empty_valid_codes) + if is_response_empty_and_successful and return_empty_response: + return res + + return self.cast_response(res, resp_type) + + def cast_response(self, res, resp_type, raise_on_error=True): + resp_type = resp_type.lower() + try: + if resp_type == 'json': + return res.json() + if resp_type == 'text': + return res.text + if resp_type == 'content': + return res.content + if resp_type == 'xml': + ET.fromstring(res.text) + if resp_type == 'response': + return res + return res + except ValueError as exception: + if raise_on_error: + raise DemistoException('Failed to parse {} object from response: {}' # type: ignore[str-bytes-safe] + .format(resp_type, res.content), exception, res) + + def _update_metrics(self, res, success): + """ Updates execution metrics based on response and success flag. + + :type response: ``requests.Response`` + :param response: Response from API after the request for which to check error type + + :type success: ``bool`` + :param success: Wheter the request succeeded or failed + """ + if success: + if not self.is_polling_in_progress(res): + self.execution_metrics.success += 1 + else: + error_type = self.determine_error_type(res) + if error_type == ErrorTypes.QUOTA_ERROR: + self.execution_metrics.quota_error += 1 + elif error_type == ErrorTypes.AUTH_ERROR: + self.execution_metrics.auth_error += 1 + elif error_type == ErrorTypes.SERVICE_ERROR: + self.execution_metrics.service_error += 1 + elif error_type == ErrorTypes.GENERAL_ERROR: + self.execution_metrics.general_error += 1 + + def determine_error_type(self, response): + """ Determines the type of error based on response status code and content. + Note: this method can be overriden by subclass when implementing execution metrics. + + :type response: ``requests.Response`` + :param response: Response from API after the request for which to check error type + + :return: The error type if found, otherwise None + :rtype: ``ErrorTypes`` + """ + if response.status_code == 401: + return ErrorTypes.AUTH_ERROR + elif response.status_code == 429: + return ErrorTypes.QUOTA_ERROR + elif response.status_code == 500: + return ErrorTypes.SERVICE_ERROR + return ErrorTypes.GENERAL_ERROR + + def is_polling_in_progress(self, response): + """If thie response indicates polling operation in progress, return True. + Note: this method should be overriden by subclass when implementing polling reputation commands + with execution metrics. + + :type response: ``requests.Response`` + :param response: Response from API after the request for which to check the polling status + + :return: Whether the response indicates polling in progress + :rtype: ``bool`` + """ + return False + def _is_status_code_valid(self, response, ok_codes=None): """If the status code is OK, return 'True'. @@ -9087,6 +9224,12 @@ def client_error_handler(self, res): err_msg += '\n{}'.format(res.text) raise DemistoException(err_msg, res=res) + def _return_execution_metrics_results(self): + """ Returns execution metrics results. + """ + if self.execution_metrics.metrics: + return_results(cast(CommandResults, self.execution_metrics.metrics)) + def batch(iterable, batch_size=1): """Gets an iterable and yields slices of it. diff --git a/Packs/Base/Scripts/CommonServerPython/CommonServerPython_test.py b/Packs/Base/Scripts/CommonServerPython/CommonServerPython_test.py index 74de2379560d..f320123f3cc8 100644 --- a/Packs/Base/Scripts/CommonServerPython/CommonServerPython_test.py +++ b/Packs/Base/Scripts/CommonServerPython/CommonServerPython_test.py @@ -3134,6 +3134,227 @@ def test_http_request_params_parser_none(self, requests_mock): assert mock_request.last_request.query == 'key=value+with+spaces' + def test_http_request_execution_metrics_success(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A successful response. + Then: Verify the successful execution metrics is incremented. + """ + requests_mock.get('http://example.com/api/v2/event', text="success") + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + client._http_request('get', 'event', resp_type='response', with_metrics=True) + assert client.execution_metrics.success == 1 + + def test_http_request_execution_metrics_success_but_polling_in_progress(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A successful response. + - Response is determined as polling in progress. + Then: Verify the successful execution metrics is not incremented. + """ + requests_mock.get('http://example.com/api/v2/event', text="success") + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + client.is_polling_in_progress = lambda _: True + client._http_request('get', 'event', resp_type='response', with_metrics=True) + assert client.execution_metrics.success == 0 + + def test_http_request_execution_metrics_timeout(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A timeout error is returned. + Then: Verify the timeout error execution metrics is incremented. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', exc=requests.exceptions.ConnectTimeout) + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException): + client._http_request('get', 'event', resp_type='response', with_metrics=True) + assert client.execution_metrics.timeout_error == 1 + + def test_http_request_execution_metrics_ssl_error(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - An SSL error is returned. + Then: Verify the ssl error execution metrics is incremented. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', exc=requests.exceptions.SSLError) + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201)) + with raises(DemistoException): + client._http_request('get', 'event', resp_type='response', with_metrics=True) + assert client.execution_metrics.ssl_error == 1 + + def test_http_request_execution_metrics_proxy_error(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A proxy error is returned. + Then: Verify the proxy error execution metrics is incremented. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', exc=requests.exceptions.ProxyError) + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException): + client._http_request('get', 'event', resp_type='response', with_metrics=True) + assert client.execution_metrics.proxy_error == 1 + + def test_http_request_execution_metrics_connection_error(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A connection error is returned. + Then: Verify the connection error execution metrics is incremented. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', exc=requests.exceptions.ConnectionError) + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException): + client._http_request('get', 'event', resp_type='response', with_metrics=True) + assert client.execution_metrics.connection_error == 1 + + def test_http_request_execution_metrics_retry_error(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A retry error is returned. + Then: Verify the retry error execution metrics is incremented. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', exc=requests.exceptions.RetryError) + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException): + client._http_request('get', 'event', resp_type='response', with_metrics=True) + assert client.execution_metrics.retry_error == 1 + + def test_http_request_execution_metrics_auth_error(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - An auth error (401 status code) is returned. + Then: Verify the auth error execution metrics is incremented. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', status_code=401, text="err") + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException, match="Error in API call"): + client._http_request('get', 'event', with_metrics=True) + assert client.execution_metrics.auth_error == 1 + + def test_http_request_execution_metrics_quota_error(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A quota error (429 status code) is returned. + Then: Verify the quota error execution metrics is incremented. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', status_code=429, text="err") + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException, match="Error in API call"): + client._http_request('get', 'event', with_metrics=True) + assert client.execution_metrics.quota_error == 1 + + def test_http_request_execution_metrics_service_error(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A service error (500 status code) is returned. + Then: Verify the service error execution metrics is incremented. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', status_code=500, text="err") + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException, match="Error in API call"): + client._http_request('get', 'event', with_metrics=True) + assert client.execution_metrics.service_error == 1 + + def test_http_request_execution_metrics_general_error(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A general error (400 status code) is returned. + Then: Verify the general error execution metrics is incremented. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', status_code=400, text="err") + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException, match="Error in API call"): + client._http_request('get', 'event', with_metrics=True) + assert client.execution_metrics.general_error == 1 + + def test_http_request_execution_metrics_not_found_error_but_ok(cls, requests_mock): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - A not found error (404 status code) is returned. + - 404 is considered ok + Then: Verify the success execution metrics is incremented, and not the general error metrics. + """ + requests_mock.get('http://example.com/api/v2/event', status_code=404, text="err") + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201, 404), verify=False) + res = client._http_request('get', 'event', resp_type='response', with_metrics=True) + assert res.status_code == 404 + assert client.execution_metrics.success == 1 + assert client.execution_metrics.general_error == 0 + + def test_http_request_execution_metrics_results(cls, requests_mock, mocker): + """ + Given: A BaseClient object + When: + - Calling _http_request function with metrics + - An general error is returned + - The client object is then deleted + Then: Verify an execution metrics entry is sent to demisto.results() accordingly. + """ + from CommonServerPython import DemistoException, EntryType, ErrorTypes + requests_mock.get('http://example.com/api/v2/event', status_code=400, text="err") + demisto_results_mock = mocker.patch.object(demisto, 'results') + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException, match="Error in API call"): + client._http_request('get', 'event', with_metrics=True) + del client + demisto_results_mock.assert_called_once + entry = demisto_results_mock.call_args[0][0] + assert entry["Type"] == EntryType.EXECUTION_METRICS + assert entry["APIExecutionMetrics"] == [{ + "Type": ErrorTypes.GENERAL_ERROR, + "APICallsCount": 1, + }] + + def test_http_request_no_execution_metrics_results(cls, requests_mock, mocker): + """ + Given: A BaseClient object + When: + - Calling _http_request function without metrics + - An general error is returned + - The client object is then deleted + Then: Verify demisto.results() is not called. + """ + from CommonServerPython import DemistoException + requests_mock.get('http://example.com/api/v2/event', status_code=400, text="err") + demisto_results_mock = mocker.patch.object(demisto, 'results') + client = cls.BaseClient('http://example.com/api/v2/', ok_codes=(200, 201), verify=False) + with raises(DemistoException, match="Error in API call"): + client._http_request('get', 'event') + del client + demisto_results_mock.assert_not_called + @pytest.mark.skipif(not IS_PY3, reason='test not supported in py2') def test_http_request_params_parser_quote(self, requests_mock): """ diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index 21eda318c044..626f953c6d96 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.33.32", + "currentVersion": "1.33.33", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", diff --git a/Packs/EmailHippo/Integrations/EmailHippo/EmailHippo.py b/Packs/EmailHippo/Integrations/EmailHippo/EmailHippo.py index 57a5e567c39d..6f9dd03acc88 100644 --- a/Packs/EmailHippo/Integrations/EmailHippo/EmailHippo.py +++ b/Packs/EmailHippo/Integrations/EmailHippo/EmailHippo.py @@ -34,7 +34,6 @@ def __init__(self, more_api_key, whois_api_key, more_server_url, whois_server_ur self._whois_api_key = whois_api_key self._more_server_url = more_server_url.rstrip("/") self._whois_server_url = f'{whois_server_url.rstrip("/")}/v1/{whois_api_key}' - self.execution_metrics = ExecutionMetrics() super().__init__(base_url='', **kwargs) @@ -48,8 +47,11 @@ def get_email_reputation(self, email: str) -> dict[str, Any]: dict: dict containing the Email reputation as returned from the API """ - return self._http_request(method='GET', - full_url=f'{self._more_server_url}/v3/more/json/{self._more_api_key}/{email}') + return self._http_request( + method='GET', + full_url=f'{self._more_server_url}/v3/more/json/{self._more_api_key}/{email}', + with_metrics=True, + ) def get_domain_reputation(self, domain: str) -> dict[str, Any]: """ @@ -62,39 +64,34 @@ def get_domain_reputation(self, domain: str) -> dict[str, Any]: dict: dict containing the domain reputation as returned from the API. """ - return self._http_request(method='GET', full_url=f'{self._whois_server_url}/{domain}') + return self._http_request( + method='GET', + full_url=f'{self._whois_server_url}/{domain}', + with_metrics=True, + ) def get_email_quota(self) -> dict[str, Any]: """ Get the email quota remaining for the API key """ - return self._http_request(method='GET', - full_url=f'{self._more_server_url}/customer/reports/v3/quota/{self._more_api_key}') + return self._http_request( + method='GET', + full_url=f'{self._more_server_url}/customer/reports/v3/quota/{self._more_api_key}', + with_metrics=True, + ) - def error_handler(self, res: Response): - """ - Error handling for http responses, to support the API Execution Metrics. + def determine_error_type(self, res: Response): + """ Determines the error type based on response. Args: res (Response): The response object from the http request. - """ - if res.status_code == 429 or 'Insufficient quota' in res.text: - self.execution_metrics.quota_error += 1 - elif res.status_code == 401: - self.execution_metrics.auth_error += 1 - else: - self.execution_metrics.general_error += 1 - - self.client_error_handler(res) - def _http_request(self, **kwargs): - """ - Wrapper for BaseClient._http_request for supporting API Execution Metrics. + Returns: + (ErrorTypes): The error type determined. """ - try: - return super()._http_request(error_handler=self.error_handler, **kwargs) - finally: - self.execution_metrics.success += 1 + if 'Insufficient quota' in res.text: + return ErrorTypes.QUOTA_ERROR + return super().determine_error_type(res) def parse_domain_date(domain_date: list[str] | str, date_format: str = '%Y-%m-%dT%H:%M:%S.000Z') -> str | None: @@ -391,12 +388,10 @@ def main() -> None: # pragma: no cover else: raise NotImplementedError(f'Command {command} is not implemented') if res: - return_results(append_metrics(client.execution_metrics, res)) + return_results(res) # Log exceptions and return errors except Exception as e: - if client: - return_results(client.execution_metrics.metrics) return_error(f'Failed to execute {command} command.\nError:\n{str(e)}') diff --git a/Packs/EmailHippo/Integrations/EmailHippo/EmailHippo_test.py b/Packs/EmailHippo/Integrations/EmailHippo/EmailHippo_test.py index cd3f7abf074f..5bdfe55271fa 100644 --- a/Packs/EmailHippo/Integrations/EmailHippo/EmailHippo_test.py +++ b/Packs/EmailHippo/Integrations/EmailHippo/EmailHippo_test.py @@ -16,14 +16,15 @@ def load_test_data(path): class TestHappyPath: - def test_get_email_reputation_success(self, requests_mock, client): + def test_get_email_reputation_success(self, requests_mock, client: Client): """ Given: a Client instance and a mocked API response When: get_email_reputation is called with a valid email address Then: - result returned as expected + - result returned as expected + - execution metrics success is raised by 1 """ requests_mock.get('https://test.com/v3/more/json/test/test@example.com', json=load_test_data('test_data/get_email_output.json')['api_result']) @@ -37,8 +38,9 @@ def test_get_email_reputation_success(self, requests_mock, client): actual_entry_context = command_res[0].to_context()['EntryContext'] assert expected_entry_context == actual_entry_context assert all(key in command_res[0].readable_output for key in hr_keys) + assert client.execution_metrics.success == 1 - def test_domain_reputation_command_success(self, requests_mock, client): + def test_domain_reputation_command_success(self, requests_mock, client: Client): """ Given: - a Client instance and a mocked API response @@ -46,6 +48,7 @@ def test_domain_reputation_command_success(self, requests_mock, client): - domain_reputation_command is called with a valid domain Then: - result returned as expected + - execution metrics success is raised by 1 """ requests_mock.get('https://test.com/v1/test/example.com', json=load_test_data('test_data/get_domain_output.json')['api_result']) @@ -64,8 +67,9 @@ def test_domain_reputation_command_success(self, requests_mock, client): actual_entry_context = command_res[0].to_context()['EntryContext'] assert expected_entry_context == actual_entry_context assert all(key in command_res[0].readable_output for key in hr_keys) + assert client.execution_metrics.success == 1 - def test_quota_command_success(self, requests_mock, client): + def test_quota_command_success(self, requests_mock, client: Client): """ Given: - a Client instance and a mocked API response @@ -73,6 +77,7 @@ def test_quota_command_success(self, requests_mock, client): - get_email_quota_command is called with a valid domain Then: - result returned as expected + - execution metrics success is raised by 1 """ requests_mock.get('https://test.com/customer/reports/v3/quota/test', json=load_test_data('test_data/get_quota_output.json')) @@ -86,11 +91,12 @@ def test_quota_command_success(self, requests_mock, client): assert command_res assert all(key in command_res.readable_output for key in hr_keys) assert 'licenseKey' not in command_res.outputs + assert client.execution_metrics.success == 1 class TestFailure: - def test_get_email_reputation_failure_quota_limit(self, requests_mock, client): + def test_get_email_reputation_failure_quota_limit(self, requests_mock, client: Client): """ Given: a Client instance and a mocked failed quota limit API response @@ -108,3 +114,41 @@ def test_get_email_reputation_failure_quota_limit(self, requests_mock, client): with pytest.raises(DemistoException): client.get_email_reputation('test@example.com') assert client.execution_metrics.quota_error == 1 + + def test_get_email_reputation_failure_auth_error(self, requests_mock, client: Client): + """ + Given: + a Client instance and a mocked failed auth limit API response + When: + get_email_reputation is called with a valid email address + Then: + - a DemistoException is raised + - matrix auth_error increased + """ + requests_mock.get( + 'https://test.com/v3/more/json/test/test@example.com', + status_code=401, + ) + + with pytest.raises(DemistoException): + client.get_email_reputation('test@example.com') + assert client.execution_metrics.auth_error == 1 + + def test_get_email_reputation_failure_general_error(self, requests_mock, client: Client): + """ + Given: + a Client instance and a mocked 400 API response + When: + get_email_reputation is called with a valid email address + Then: + - a DemistoException is raised + - matrix general_error increased + """ + requests_mock.get( + 'https://test.com/v3/more/json/test/test@example.com', + status_code=400, + ) + + with pytest.raises(DemistoException): + client.get_email_reputation('test@example.com') + assert client.execution_metrics.general_error == 1 diff --git a/Packs/EmailHippo/ReleaseNotes/1_0_4.md b/Packs/EmailHippo/ReleaseNotes/1_0_4.md new file mode 100644 index 000000000000..df804f622c59 --- /dev/null +++ b/Packs/EmailHippo/ReleaseNotes/1_0_4.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Email Hippo + +- Internal improvements in execution metrics collection. diff --git a/Packs/EmailHippo/pack_metadata.json b/Packs/EmailHippo/pack_metadata.json index 31e23d3c01e7..60e811d836b7 100644 --- a/Packs/EmailHippo/pack_metadata.json +++ b/Packs/EmailHippo/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Email Hippo", "description": "Use this tool to verify email sources as fake emails that were used as part of phishing attacks.", "support": "xsoar", - "currentVersion": "1.0.3", + "currentVersion": "1.0.4", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 0b947a0333858b2fbc2d5e810c07669be7792b7a Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Tue, 20 Feb 2024 09:00:29 +0200 Subject: [PATCH 029/272] Update Docker Image To demisto/boto3py3 (#33008) * Updated Metadata Of Pack AWS-CloudTrail * Added release notes to pack AWS-CloudTrail * Packs/AWS-CloudTrail/Integrations/AWS-CloudTrail/AWS-CloudTrail.yml Docker image update --- .../Integrations/AWS-CloudTrail/AWS-CloudTrail.yml | 2 +- Packs/AWS-CloudTrail/ReleaseNotes/1_0_11.md | 3 +++ Packs/AWS-CloudTrail/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/AWS-CloudTrail/ReleaseNotes/1_0_11.md diff --git a/Packs/AWS-CloudTrail/Integrations/AWS-CloudTrail/AWS-CloudTrail.yml b/Packs/AWS-CloudTrail/Integrations/AWS-CloudTrail/AWS-CloudTrail.yml index 898dc1bc0ead..833ea287a3b9 100644 --- a/Packs/AWS-CloudTrail/Integrations/AWS-CloudTrail/AWS-CloudTrail.yml +++ b/Packs/AWS-CloudTrail/Integrations/AWS-CloudTrail/AWS-CloudTrail.yml @@ -371,7 +371,7 @@ script: - contextPath: AWS.CloudTrail.Events.CloudTrailEvent description: A JSON string that contains a representation of the event returned. type: string - dockerimage: demisto/boto3py3:1.0.0.86958 + dockerimage: demisto/boto3py3:1.0.0.88114 runonce: false script: '-' subtype: python3 diff --git a/Packs/AWS-CloudTrail/ReleaseNotes/1_0_11.md b/Packs/AWS-CloudTrail/ReleaseNotes/1_0_11.md new file mode 100644 index 000000000000..9885337e7ce1 --- /dev/null +++ b/Packs/AWS-CloudTrail/ReleaseNotes/1_0_11.md @@ -0,0 +1,3 @@ +#### Integrations +##### AWS - CloudTrail +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88114*. diff --git a/Packs/AWS-CloudTrail/pack_metadata.json b/Packs/AWS-CloudTrail/pack_metadata.json index 15c81b4fd6e0..9080c6a6e3aa 100644 --- a/Packs/AWS-CloudTrail/pack_metadata.json +++ b/Packs/AWS-CloudTrail/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - CloudTrail", "description": "Amazon Web Services CloudTrail.", "support": "xsoar", - "currentVersion": "1.0.10", + "currentVersion": "1.0.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e4ee446b3681f3479c32a80bafd66efa50ccb2b7 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Tue, 20 Feb 2024 09:02:50 +0200 Subject: [PATCH 030/272] Update Docker Image To demisto/python3 (#33007) * Updated Metadata Of Pack DomainToolsIrisDetect * Added release notes to pack DomainToolsIrisDetect * Packs/DomainToolsIrisDetect/Integrations/DomainToolsIrisDetect/DomainToolsIrisDetect.yml Docker image update * Updated Metadata Of Pack AtlassianConfluenceCloud * Added release notes to pack AtlassianConfluenceCloud * Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml Docker image update * Updated Metadata Of Pack Gatewatcher-AionIQ * Added release notes to pack Gatewatcher-AionIQ * Packs/Gatewatcher-AionIQ/Integrations/GCenter/GCenter.yml Docker image update * Updated Metadata Of Pack McAfeeNSM * Added release notes to pack McAfeeNSM * Packs/McAfeeNSM/Integrations/McAfeeNSMv2/McAfeeNSMv2.yml Docker image update * Updated Metadata Of Pack RecordedFutureASI * Added release notes to pack RecordedFutureASI * Packs/RecordedFutureASI/Integrations/RecordedFutureASI/RecordedFutureASI.yml Docker image update * Updated Metadata Of Pack Securonix * Added release notes to pack Securonix * Packs/Securonix/Integrations/Securonix/Securonix.yml Docker image update * Updated Metadata Of Pack NetBox * Added release notes to pack NetBox * Packs/NetBox/Integrations/NetBoxEventCollector/NetBoxEventCollector.yml Docker image update * Updated Metadata Of Pack SentinelOne * Added release notes to pack SentinelOne * Packs/SentinelOne/Integrations/SentinelOneEventCollector/SentinelOneEventCollector.yml Docker image update * Updated Metadata Of Pack illuminate * Added release notes to pack illuminate * Packs/illuminate/Integrations/Analyst1/Analyst1.yml Docker image update * Updated Metadata Of Pack DeHashed * Added release notes to pack DeHashed * Packs/DeHashed/Integrations/DeHashed/DeHashed.yml Docker image update --- .../AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml | 2 +- Packs/AtlassianConfluenceCloud/ReleaseNotes/1_0_24.md | 3 +++ Packs/AtlassianConfluenceCloud/pack_metadata.json | 2 +- Packs/DeHashed/Integrations/DeHashed/DeHashed.yml | 2 +- Packs/DeHashed/ReleaseNotes/1_1_25.md | 3 +++ Packs/DeHashed/pack_metadata.json | 2 +- .../DomainToolsIrisDetect/DomainToolsIrisDetect.yml | 2 +- Packs/DomainToolsIrisDetect/ReleaseNotes/1_0_11.md | 3 +++ Packs/DomainToolsIrisDetect/pack_metadata.json | 2 +- Packs/Gatewatcher-AionIQ/Integrations/GCenter/GCenter.yml | 2 +- Packs/Gatewatcher-AionIQ/ReleaseNotes/1_1_20.md | 3 +++ Packs/Gatewatcher-AionIQ/pack_metadata.json | 2 +- Packs/McAfeeNSM/Integrations/McAfeeNSMv2/McAfeeNSMv2.yml | 2 +- Packs/McAfeeNSM/ReleaseNotes/1_2_16.md | 3 +++ Packs/McAfeeNSM/pack_metadata.json | 2 +- .../Integrations/NetBoxEventCollector/NetBoxEventCollector.yml | 2 +- Packs/NetBox/ReleaseNotes/1_0_17.md | 3 +++ Packs/NetBox/pack_metadata.json | 2 +- .../Integrations/RecordedFutureASI/RecordedFutureASI.yml | 2 +- Packs/RecordedFutureASI/ReleaseNotes/2_0_14.md | 3 +++ Packs/RecordedFutureASI/pack_metadata.json | 2 +- Packs/Securonix/Integrations/Securonix/Securonix.yml | 2 +- Packs/Securonix/ReleaseNotes/2_0_19.md | 3 +++ Packs/Securonix/pack_metadata.json | 2 +- .../SentinelOneEventCollector/SentinelOneEventCollector.yml | 2 +- Packs/SentinelOne/ReleaseNotes/3_2_21.md | 3 +++ Packs/SentinelOne/pack_metadata.json | 2 +- Packs/illuminate/Integrations/Analyst1/Analyst1.yml | 2 +- Packs/illuminate/ReleaseNotes/1_1_8.md | 3 +++ Packs/illuminate/pack_metadata.json | 2 +- 30 files changed, 50 insertions(+), 20 deletions(-) create mode 100644 Packs/AtlassianConfluenceCloud/ReleaseNotes/1_0_24.md create mode 100644 Packs/DeHashed/ReleaseNotes/1_1_25.md create mode 100644 Packs/DomainToolsIrisDetect/ReleaseNotes/1_0_11.md create mode 100644 Packs/Gatewatcher-AionIQ/ReleaseNotes/1_1_20.md create mode 100644 Packs/McAfeeNSM/ReleaseNotes/1_2_16.md create mode 100644 Packs/NetBox/ReleaseNotes/1_0_17.md create mode 100644 Packs/RecordedFutureASI/ReleaseNotes/2_0_14.md create mode 100644 Packs/Securonix/ReleaseNotes/2_0_19.md create mode 100644 Packs/SentinelOne/ReleaseNotes/3_2_21.md create mode 100644 Packs/illuminate/ReleaseNotes/1_1_8.md diff --git a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml index 758df2f41e7e..0faaf6cabda5 100644 --- a/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml +++ b/Packs/AtlassianConfluenceCloud/Integrations/AtlassianConfluenceCloud/AtlassianConfluenceCloud.yml @@ -1915,7 +1915,7 @@ script: - contextPath: ConfluenceCloud.Group._links.self description: Link to the group. type: String - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 runonce: false script: '-' subtype: python3 diff --git a/Packs/AtlassianConfluenceCloud/ReleaseNotes/1_0_24.md b/Packs/AtlassianConfluenceCloud/ReleaseNotes/1_0_24.md new file mode 100644 index 000000000000..b52379b8a23d --- /dev/null +++ b/Packs/AtlassianConfluenceCloud/ReleaseNotes/1_0_24.md @@ -0,0 +1,3 @@ +#### Integrations +##### Atlassian Confluence Cloud +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/AtlassianConfluenceCloud/pack_metadata.json b/Packs/AtlassianConfluenceCloud/pack_metadata.json index d00cb055a8e2..862ecd626a25 100644 --- a/Packs/AtlassianConfluenceCloud/pack_metadata.json +++ b/Packs/AtlassianConfluenceCloud/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Atlassian Confluence Cloud", "description": "Atlassian Confluence Cloud allows users to interact with confluence entities like content, space, users and groups. Users can also manage the space permissions.", "support": "xsoar", - "currentVersion": "1.0.23", + "currentVersion": "1.0.24", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/DeHashed/Integrations/DeHashed/DeHashed.yml b/Packs/DeHashed/Integrations/DeHashed/DeHashed.yml index 675537c7f64d..c0906311829e 100644 --- a/Packs/DeHashed/Integrations/DeHashed/DeHashed.yml +++ b/Packs/DeHashed/Integrations/DeHashed/DeHashed.yml @@ -179,7 +179,7 @@ script: - contextPath: DBotScore.Reliability description: Reliability of the source providing the intelligence data. type: String - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 runonce: false script: '-' subtype: python3 diff --git a/Packs/DeHashed/ReleaseNotes/1_1_25.md b/Packs/DeHashed/ReleaseNotes/1_1_25.md new file mode 100644 index 000000000000..871cb0d978f0 --- /dev/null +++ b/Packs/DeHashed/ReleaseNotes/1_1_25.md @@ -0,0 +1,3 @@ +#### Integrations +##### DeHashed +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/DeHashed/pack_metadata.json b/Packs/DeHashed/pack_metadata.json index 872dd52e2c40..9d28344c2d2a 100644 --- a/Packs/DeHashed/pack_metadata.json +++ b/Packs/DeHashed/pack_metadata.json @@ -2,7 +2,7 @@ "name": "DeHashed", "description": "This integration allows you to check if your personal information such as your email, username, or password is being compromised.", "support": "xsoar", - "currentVersion": "1.1.24", + "currentVersion": "1.1.25", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/DomainToolsIrisDetect/Integrations/DomainToolsIrisDetect/DomainToolsIrisDetect.yml b/Packs/DomainToolsIrisDetect/Integrations/DomainToolsIrisDetect/DomainToolsIrisDetect.yml index 215e25f84186..a736f4c956d1 100644 --- a/Packs/DomainToolsIrisDetect/Integrations/DomainToolsIrisDetect/DomainToolsIrisDetect.yml +++ b/Packs/DomainToolsIrisDetect/Integrations/DomainToolsIrisDetect/DomainToolsIrisDetect.yml @@ -1044,7 +1044,7 @@ script: type: String - description: This command will reset your fetch history. name: domaintools-iris-detect-reset-fetch-indicators - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true runonce: false script: '-' diff --git a/Packs/DomainToolsIrisDetect/ReleaseNotes/1_0_11.md b/Packs/DomainToolsIrisDetect/ReleaseNotes/1_0_11.md new file mode 100644 index 000000000000..217ca7caee2e --- /dev/null +++ b/Packs/DomainToolsIrisDetect/ReleaseNotes/1_0_11.md @@ -0,0 +1,3 @@ +#### Integrations +##### DomainTools Iris Detect +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/DomainToolsIrisDetect/pack_metadata.json b/Packs/DomainToolsIrisDetect/pack_metadata.json index a056185b9366..4c3c332391e8 100644 --- a/Packs/DomainToolsIrisDetect/pack_metadata.json +++ b/Packs/DomainToolsIrisDetect/pack_metadata.json @@ -2,7 +2,7 @@ "name": "DomainTools Iris Detect", "description": "Iris Detect protects against malicious domains impersonating your brands and supply chain.", "support": "partner", - "currentVersion": "1.0.10", + "currentVersion": "1.0.11", "author": "DomainTools Integrations", "url": "http://www.domaintools.com", "email": "enterprisesupport@domaintools.com", diff --git a/Packs/Gatewatcher-AionIQ/Integrations/GCenter/GCenter.yml b/Packs/Gatewatcher-AionIQ/Integrations/GCenter/GCenter.yml index ee80881eabb3..3436a167bfe2 100644 --- a/Packs/Gatewatcher-AionIQ/Integrations/GCenter/GCenter.yml +++ b/Packs/Gatewatcher-AionIQ/Integrations/GCenter/GCenter.yml @@ -1312,7 +1312,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 fromversion: 6.2.0 tests: - Gcenter Test Playbook diff --git a/Packs/Gatewatcher-AionIQ/ReleaseNotes/1_1_20.md b/Packs/Gatewatcher-AionIQ/ReleaseNotes/1_1_20.md new file mode 100644 index 000000000000..ef5a67a424cd --- /dev/null +++ b/Packs/Gatewatcher-AionIQ/ReleaseNotes/1_1_20.md @@ -0,0 +1,3 @@ +#### Integrations +##### GCenter +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/Gatewatcher-AionIQ/pack_metadata.json b/Packs/Gatewatcher-AionIQ/pack_metadata.json index 36a921d2e03b..c3387c6af759 100644 --- a/Packs/Gatewatcher-AionIQ/pack_metadata.json +++ b/Packs/Gatewatcher-AionIQ/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Gatewatcher AionIQ", "description": "This pack provide integration with Gatewatcher NDR solution : AIonIQ", "support": "partner", - "currentVersion": "1.1.19", + "currentVersion": "1.1.20", "author": "Gatewatcher", "url": "https://www.gatewatcher.com/", "email": "integration@gatewatcher.com", diff --git a/Packs/McAfeeNSM/Integrations/McAfeeNSMv2/McAfeeNSMv2.yml b/Packs/McAfeeNSM/Integrations/McAfeeNSMv2/McAfeeNSMv2.yml index 0f469cbee0a0..85fb62e2d1ef 100644 --- a/Packs/McAfeeNSM/Integrations/McAfeeNSMv2/McAfeeNSMv2.yml +++ b/Packs/McAfeeNSM/Integrations/McAfeeNSMv2/McAfeeNSMv2.yml @@ -2045,7 +2045,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 fromversion: 6.5.0 tests: - Test_McAfeeNSMv2_using_v9 diff --git a/Packs/McAfeeNSM/ReleaseNotes/1_2_16.md b/Packs/McAfeeNSM/ReleaseNotes/1_2_16.md new file mode 100644 index 000000000000..c2e4341e3453 --- /dev/null +++ b/Packs/McAfeeNSM/ReleaseNotes/1_2_16.md @@ -0,0 +1,3 @@ +#### Integrations +##### McAfee NSM v2 +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/McAfeeNSM/pack_metadata.json b/Packs/McAfeeNSM/pack_metadata.json index 368918588d24..da60f8f9d38a 100644 --- a/Packs/McAfeeNSM/pack_metadata.json +++ b/Packs/McAfeeNSM/pack_metadata.json @@ -2,7 +2,7 @@ "name": "McAfee NSM", "description": "McAfee Network Security Manager", "support": "xsoar", - "currentVersion": "1.2.15", + "currentVersion": "1.2.16", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/NetBox/Integrations/NetBoxEventCollector/NetBoxEventCollector.yml b/Packs/NetBox/Integrations/NetBoxEventCollector/NetBoxEventCollector.yml index f12869e45cfc..9b29c7b382cb 100644 --- a/Packs/NetBox/Integrations/NetBoxEventCollector/NetBoxEventCollector.yml +++ b/Packs/NetBox/Integrations/NetBoxEventCollector/NetBoxEventCollector.yml @@ -58,7 +58,7 @@ script: name: limit description: Gets events from NetBox. name: netbox-get-events - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetchevents: true script: '-' subtype: python3 diff --git a/Packs/NetBox/ReleaseNotes/1_0_17.md b/Packs/NetBox/ReleaseNotes/1_0_17.md new file mode 100644 index 000000000000..30e5c4f31c56 --- /dev/null +++ b/Packs/NetBox/ReleaseNotes/1_0_17.md @@ -0,0 +1,3 @@ +#### Integrations +##### NetBox Event Collector +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/NetBox/pack_metadata.json b/Packs/NetBox/pack_metadata.json index ca8d7f51a653..2e3139cd6b87 100644 --- a/Packs/NetBox/pack_metadata.json +++ b/Packs/NetBox/pack_metadata.json @@ -2,7 +2,7 @@ "name": "NetBox", "description": "This is the NetBox event collector integration for XSIAM", "support": "xsoar", - "currentVersion": "1.0.16", + "currentVersion": "1.0.17", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/RecordedFutureASI/Integrations/RecordedFutureASI/RecordedFutureASI.yml b/Packs/RecordedFutureASI/Integrations/RecordedFutureASI/RecordedFutureASI.yml index 4b623189ef4d..2cd8bf3c2738 100644 --- a/Packs/RecordedFutureASI/Integrations/RecordedFutureASI/RecordedFutureASI.yml +++ b/Packs/RecordedFutureASI/Integrations/RecordedFutureASI/RecordedFutureASI.yml @@ -77,7 +77,7 @@ script: - name: expand_issues description: true/false to make an incident per host & per new issue. description: Gets the issues for a project from a particular snapshot (defaults to recent). - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true subtype: python3 fromversion: 6.5.0 diff --git a/Packs/RecordedFutureASI/ReleaseNotes/2_0_14.md b/Packs/RecordedFutureASI/ReleaseNotes/2_0_14.md new file mode 100644 index 000000000000..a8c795914f9d --- /dev/null +++ b/Packs/RecordedFutureASI/ReleaseNotes/2_0_14.md @@ -0,0 +1,3 @@ +#### Integrations +##### Recorded Future Attack Surface Intelligence +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/RecordedFutureASI/pack_metadata.json b/Packs/RecordedFutureASI/pack_metadata.json index 6bb72621ec73..1534038082e5 100644 --- a/Packs/RecordedFutureASI/pack_metadata.json +++ b/Packs/RecordedFutureASI/pack_metadata.json @@ -3,7 +3,7 @@ "prevName": "Recorded Future ASI", "description": "Helps you take risk prioritization to the next level by helping you identify the biggest weaknesses within your attack surface.", "support": "partner", - "currentVersion": "2.0.13", + "currentVersion": "2.0.14", "author": "Recorded Future", "url": "", "email": "support@recordedfuture.com", diff --git a/Packs/Securonix/Integrations/Securonix/Securonix.yml b/Packs/Securonix/Integrations/Securonix/Securonix.yml index 1da626cbdb21..265cbdb28437 100644 --- a/Packs/Securonix/Integrations/Securonix/Securonix.yml +++ b/Packs/Securonix/Integrations/Securonix/Securonix.yml @@ -1546,7 +1546,7 @@ script: required: true description: Deletes the entries from the lookup table. name: securonix-lookup-table-entries-delete - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true runonce: false script: '-' diff --git a/Packs/Securonix/ReleaseNotes/2_0_19.md b/Packs/Securonix/ReleaseNotes/2_0_19.md new file mode 100644 index 000000000000..dbf7bad0ab50 --- /dev/null +++ b/Packs/Securonix/ReleaseNotes/2_0_19.md @@ -0,0 +1,3 @@ +#### Integrations +##### Securonix +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/Securonix/pack_metadata.json b/Packs/Securonix/pack_metadata.json index 16707e559048..0a5c18a45c04 100644 --- a/Packs/Securonix/pack_metadata.json +++ b/Packs/Securonix/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Securonix", "description": "Use the Securonix integration to manage incidents, threats, lookup tables, whitelists and watchlists.", "support": "partner", - "currentVersion": "2.0.18", + "currentVersion": "2.0.19", "author": "Securonix", "url": "https://www.securonix.com", "email": "support@securonix.com", diff --git a/Packs/SentinelOne/Integrations/SentinelOneEventCollector/SentinelOneEventCollector.yml b/Packs/SentinelOne/Integrations/SentinelOneEventCollector/SentinelOneEventCollector.yml index 44565878a681..e5cd27c26aab 100644 --- a/Packs/SentinelOne/Integrations/SentinelOneEventCollector/SentinelOneEventCollector.yml +++ b/Packs/SentinelOne/Integrations/SentinelOneEventCollector/SentinelOneEventCollector.yml @@ -72,7 +72,7 @@ script: name: limit description: Gets events from SentinelOne. name: sentinelone-get-events - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetchevents: true script: '-' subtype: python3 diff --git a/Packs/SentinelOne/ReleaseNotes/3_2_21.md b/Packs/SentinelOne/ReleaseNotes/3_2_21.md new file mode 100644 index 000000000000..12defbb398f1 --- /dev/null +++ b/Packs/SentinelOne/ReleaseNotes/3_2_21.md @@ -0,0 +1,3 @@ +#### Integrations +##### SentinelOne Event Collector +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/SentinelOne/pack_metadata.json b/Packs/SentinelOne/pack_metadata.json index c289eeee9799..f3ecb46894a6 100644 --- a/Packs/SentinelOne/pack_metadata.json +++ b/Packs/SentinelOne/pack_metadata.json @@ -2,7 +2,7 @@ "name": "SentinelOne", "description": "Endpoint protection", "support": "partner", - "currentVersion": "3.2.20", + "currentVersion": "3.2.21", "author": "SentinelOne", "url": "https://www.sentinelone.com/support/", "email": "support@sentinelone.com", diff --git a/Packs/illuminate/Integrations/Analyst1/Analyst1.yml b/Packs/illuminate/Integrations/Analyst1/Analyst1.yml index fcea93a36d0a..4c5d253433c3 100644 --- a/Packs/illuminate/Integrations/Analyst1/Analyst1.yml +++ b/Packs/illuminate/Integrations/Analyst1/Analyst1.yml @@ -746,7 +746,7 @@ script: - contextPath: Analyst1.EvidenceStatus.processingComplete description: True or false to indicate if processing of the Evidence upload is done. Determined by evaluating the id or message are present and populated. If an id is returned but blank, this is false, indicating the upload is still in progress. description: Check on the status of the analyst1-evidence-submit action by using its output UUID. - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 subtype: python3 runonce: false fromversion: 5.0.0 diff --git a/Packs/illuminate/ReleaseNotes/1_1_8.md b/Packs/illuminate/ReleaseNotes/1_1_8.md new file mode 100644 index 000000000000..8ff5b58e8c3a --- /dev/null +++ b/Packs/illuminate/ReleaseNotes/1_1_8.md @@ -0,0 +1,3 @@ +#### Integrations +##### Analyst1 +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/illuminate/pack_metadata.json b/Packs/illuminate/pack_metadata.json index c1f94dda5dde..d1e7f40cfd4d 100644 --- a/Packs/illuminate/pack_metadata.json +++ b/Packs/illuminate/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Analyst1", "description": "This integration utilizes Analyst1's system to support multiple operations to assist the cyber analyst. These include intelligence collection from any source, deployment of configured indicator or signature sets for improved boundary/host defense, and enriching XSOAR indicators with data provided by the Analyst1 REST API, such as actor and malware information, activity and reported dates, evidence and hit counts, and more. For assistance with this app and any use cases please contact support@analyst1.com.", "support": "partner", - "currentVersion": "1.1.7", + "currentVersion": "1.1.8", "author": "Analyst1", "url": "", "email": "support@analyst1.com", From f1dc701e867861bac1d4fc422d5ed5cc67c642e0 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Tue, 20 Feb 2024 09:05:02 +0200 Subject: [PATCH 031/272] Update Docker Image To demisto/googleapi-python3 (#33009) * Updated Metadata Of Pack GSuiteAdmin * Added release notes to pack GSuiteAdmin * Packs/GSuiteAdmin/Integrations/GSuiteAdmin/GSuiteAdmin.yml Docker image update * Updated Metadata Of Pack GoogleSheets * Added release notes to pack GoogleSheets * Packs/GoogleSheets/Integrations/GoogleSheets/GoogleSheets.yml Docker image update * Updated Metadata Of Pack GoogleChronicleBackstory * Added release notes to pack GoogleChronicleBackstory * Packs/GoogleChronicleBackstory/Integrations/GoogleChronicleBackstory/GoogleChronicleBackstory.yml Docker image update * Updated Metadata Of Pack GSuiteSecurityAlertCenter * Added release notes to pack GSuiteSecurityAlertCenter * Packs/GSuiteSecurityAlertCenter/Integrations/GSuiteSecurityAlertCenter/GSuiteSecurityAlertCenter.yml Docker image update * Updated Metadata Of Pack GoogleDrive * Added release notes to pack GoogleDrive * Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml Docker image update * Updated Metadata Of Pack GoogleCalendar * Added release notes to pack GoogleCalendar * Packs/GoogleCalendar/Integrations/GoogleCalendar/GoogleCalendar.yml Docker image update --- Packs/GSuiteAdmin/Integrations/GSuiteAdmin/GSuiteAdmin.yml | 2 +- Packs/GSuiteAdmin/ReleaseNotes/1_1_35.md | 3 +++ Packs/GSuiteAdmin/pack_metadata.json | 2 +- .../GSuiteSecurityAlertCenter/GSuiteSecurityAlertCenter.yml | 2 +- Packs/GSuiteSecurityAlertCenter/ReleaseNotes/1_1_42.md | 3 +++ Packs/GSuiteSecurityAlertCenter/pack_metadata.json | 2 +- .../Integrations/GoogleCalendar/GoogleCalendar.yml | 2 +- Packs/GoogleCalendar/ReleaseNotes/1_1_44.md | 3 +++ Packs/GoogleCalendar/pack_metadata.json | 2 +- .../GoogleChronicleBackstory/GoogleChronicleBackstory.yml | 2 +- Packs/GoogleChronicleBackstory/ReleaseNotes/3_1_2.md | 3 +++ Packs/GoogleChronicleBackstory/pack_metadata.json | 2 +- Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml | 2 +- Packs/GoogleDrive/ReleaseNotes/1_3_3.md | 3 +++ Packs/GoogleDrive/pack_metadata.json | 2 +- Packs/GoogleSheets/Integrations/GoogleSheets/GoogleSheets.yml | 2 +- Packs/GoogleSheets/ReleaseNotes/1_0_42.md | 3 +++ Packs/GoogleSheets/pack_metadata.json | 2 +- 18 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 Packs/GSuiteAdmin/ReleaseNotes/1_1_35.md create mode 100644 Packs/GSuiteSecurityAlertCenter/ReleaseNotes/1_1_42.md create mode 100644 Packs/GoogleCalendar/ReleaseNotes/1_1_44.md create mode 100644 Packs/GoogleChronicleBackstory/ReleaseNotes/3_1_2.md create mode 100644 Packs/GoogleDrive/ReleaseNotes/1_3_3.md create mode 100644 Packs/GoogleSheets/ReleaseNotes/1_0_42.md diff --git a/Packs/GSuiteAdmin/Integrations/GSuiteAdmin/GSuiteAdmin.yml b/Packs/GSuiteAdmin/Integrations/GSuiteAdmin/GSuiteAdmin.yml index 2bd3d2727ec0..6f30062c5c6d 100644 --- a/Packs/GSuiteAdmin/Integrations/GSuiteAdmin/GSuiteAdmin.yml +++ b/Packs/GSuiteAdmin/Integrations/GSuiteAdmin/GSuiteAdmin.yml @@ -2229,7 +2229,7 @@ script: - contextPath: GSuite.Group.nonEditableAliases description: List of the group's non-editable alias email addresses that are outside of the account's primary domain or subdomains. type: String - dockerimage: demisto/googleapi-python3:1.0.0.86179 + dockerimage: demisto/googleapi-python3:1.0.0.87804 runonce: false script: '-' subtype: python3 diff --git a/Packs/GSuiteAdmin/ReleaseNotes/1_1_35.md b/Packs/GSuiteAdmin/ReleaseNotes/1_1_35.md new file mode 100644 index 000000000000..5bfd59996574 --- /dev/null +++ b/Packs/GSuiteAdmin/ReleaseNotes/1_1_35.md @@ -0,0 +1,3 @@ +#### Integrations +##### Google Workspace Admin +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.87804*. diff --git a/Packs/GSuiteAdmin/pack_metadata.json b/Packs/GSuiteAdmin/pack_metadata.json index e967158ba738..137b8726f3cb 100644 --- a/Packs/GSuiteAdmin/pack_metadata.json +++ b/Packs/GSuiteAdmin/pack_metadata.json @@ -2,7 +2,7 @@ "name": "G Suite Admin", "description": "G Suite Admin integration with Cortex XSOAR. G Suite or Google Workspace Admin is an integration to perform an action on IT infrastructure, create users, update settings, and more administrative tasks.", "support": "xsoar", - "currentVersion": "1.1.34", + "currentVersion": "1.1.35", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GSuiteSecurityAlertCenter/Integrations/GSuiteSecurityAlertCenter/GSuiteSecurityAlertCenter.yml b/Packs/GSuiteSecurityAlertCenter/Integrations/GSuiteSecurityAlertCenter/GSuiteSecurityAlertCenter.yml index 560568651fcb..1d32875a8b1a 100644 --- a/Packs/GSuiteSecurityAlertCenter/Integrations/GSuiteSecurityAlertCenter/GSuiteSecurityAlertCenter.yml +++ b/Packs/GSuiteSecurityAlertCenter/Integrations/GSuiteSecurityAlertCenter/GSuiteSecurityAlertCenter.yml @@ -767,7 +767,7 @@ script: - contextPath: GSuiteSecurityAlert.Recover.failedAlerts.status description: Status of the failed alert recovery. type: String - dockerimage: demisto/googleapi-python3:1.0.0.86179 + dockerimage: demisto/googleapi-python3:1.0.0.87804 isfetch: true runonce: false script: '-' diff --git a/Packs/GSuiteSecurityAlertCenter/ReleaseNotes/1_1_42.md b/Packs/GSuiteSecurityAlertCenter/ReleaseNotes/1_1_42.md new file mode 100644 index 000000000000..0e3a9fdba6c3 --- /dev/null +++ b/Packs/GSuiteSecurityAlertCenter/ReleaseNotes/1_1_42.md @@ -0,0 +1,3 @@ +#### Integrations +##### G Suite Security Alert Center +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.87804*. diff --git a/Packs/GSuiteSecurityAlertCenter/pack_metadata.json b/Packs/GSuiteSecurityAlertCenter/pack_metadata.json index 4ed5316d9829..4d080083f00c 100644 --- a/Packs/GSuiteSecurityAlertCenter/pack_metadata.json +++ b/Packs/GSuiteSecurityAlertCenter/pack_metadata.json @@ -2,7 +2,7 @@ "name": "G Suite Security Alert Center", "description": "Fetch alert types, delete or recover alerts, retrieve an alert's metadata, and create or view alert feedback.", "support": "xsoar", - "currentVersion": "1.1.41", + "currentVersion": "1.1.42", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GoogleCalendar/Integrations/GoogleCalendar/GoogleCalendar.yml b/Packs/GoogleCalendar/Integrations/GoogleCalendar/GoogleCalendar.yml index 6d4e31395ae8..15514490168f 100644 --- a/Packs/GoogleCalendar/Integrations/GoogleCalendar/GoogleCalendar.yml +++ b/Packs/GoogleCalendar/Integrations/GoogleCalendar/GoogleCalendar.yml @@ -173,7 +173,7 @@ script: - contextPath: GoogleCalendar.PageToken.Acl.nextSyncToken description: Token used at a later point in time to retrieve only the entries that have changed since this result was returned. type: String - dockerimage: demisto/googleapi-python3:1.0.0.86179 + dockerimage: demisto/googleapi-python3:1.0.0.87804 runonce: false script: '-' subtype: python3 diff --git a/Packs/GoogleCalendar/ReleaseNotes/1_1_44.md b/Packs/GoogleCalendar/ReleaseNotes/1_1_44.md new file mode 100644 index 000000000000..8786d4c06422 --- /dev/null +++ b/Packs/GoogleCalendar/ReleaseNotes/1_1_44.md @@ -0,0 +1,3 @@ +#### Integrations +##### Google Calendar +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.87804*. diff --git a/Packs/GoogleCalendar/pack_metadata.json b/Packs/GoogleCalendar/pack_metadata.json index bb6ecdddeeaf..57ab053d7b5c 100644 --- a/Packs/GoogleCalendar/pack_metadata.json +++ b/Packs/GoogleCalendar/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Calendar", "description": "Google Calendar integration with Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.1.43", + "currentVersion": "1.1.44", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GoogleChronicleBackstory/Integrations/GoogleChronicleBackstory/GoogleChronicleBackstory.yml b/Packs/GoogleChronicleBackstory/Integrations/GoogleChronicleBackstory/GoogleChronicleBackstory.yml index e3e2efe5480b..6b4061d728ef 100644 --- a/Packs/GoogleChronicleBackstory/Integrations/GoogleChronicleBackstory/GoogleChronicleBackstory.yml +++ b/Packs/GoogleChronicleBackstory/Integrations/GoogleChronicleBackstory/GoogleChronicleBackstory.yml @@ -6698,7 +6698,7 @@ script: - contextPath: GoogleChronicleBackstory.Events.securityResult.urlBackToProduct description: URL to direct you to the source product console for this security event. type: String - dockerimage: demisto/googleapi-python3:1.0.0.86179 + dockerimage: demisto/googleapi-python3:1.0.0.87804 isfetch: true runonce: false script: '-' diff --git a/Packs/GoogleChronicleBackstory/ReleaseNotes/3_1_2.md b/Packs/GoogleChronicleBackstory/ReleaseNotes/3_1_2.md new file mode 100644 index 000000000000..31ae40093a33 --- /dev/null +++ b/Packs/GoogleChronicleBackstory/ReleaseNotes/3_1_2.md @@ -0,0 +1,3 @@ +#### Integrations +##### Chronicle +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.87804*. diff --git a/Packs/GoogleChronicleBackstory/pack_metadata.json b/Packs/GoogleChronicleBackstory/pack_metadata.json index 6cbd6cbfacc7..302195ec5a5c 100644 --- a/Packs/GoogleChronicleBackstory/pack_metadata.json +++ b/Packs/GoogleChronicleBackstory/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Chronicle", "description": "Retrieve Chronicle detections, impacted assets, IOC matches, and 3P alerts to enrich your XSOAR workflows.", "support": "partner", - "currentVersion": "3.1.1", + "currentVersion": "3.1.2", "certification": "certified", "author": "Chronicle", "url": "https://go.chronicle.security/contact", diff --git a/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml b/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml index f140d1a75350..3b07628af964 100644 --- a/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml +++ b/Packs/GoogleDrive/Integrations/GoogleDrive/GoogleDrive.yml @@ -3103,7 +3103,7 @@ script: - contextPath: GoogleDrive.File.Parents description: The IDs of the parent folders which contain the file. type: String - dockerimage: demisto/googleapi-python3:1.0.0.86179 + dockerimage: demisto/googleapi-python3:1.0.0.87804 isfetch: true runonce: false script: "-" diff --git a/Packs/GoogleDrive/ReleaseNotes/1_3_3.md b/Packs/GoogleDrive/ReleaseNotes/1_3_3.md new file mode 100644 index 000000000000..8403a7e195d1 --- /dev/null +++ b/Packs/GoogleDrive/ReleaseNotes/1_3_3.md @@ -0,0 +1,3 @@ +#### Integrations +##### Google Drive +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.87804*. diff --git a/Packs/GoogleDrive/pack_metadata.json b/Packs/GoogleDrive/pack_metadata.json index 59b0efe67385..f528342fa6ce 100644 --- a/Packs/GoogleDrive/pack_metadata.json +++ b/Packs/GoogleDrive/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Drive", "description": "Google Drive allows users to store files on their servers, synchronize files across devices, and share files. This integration helps you to create a new drive, query past activity and view change logs performed by the users, as well as list drives and files, and manage their permissions.", "support": "xsoar", - "currentVersion": "1.3.2", + "currentVersion": "1.3.3", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/GoogleSheets/Integrations/GoogleSheets/GoogleSheets.yml b/Packs/GoogleSheets/Integrations/GoogleSheets/GoogleSheets.yml index 599dff95d47c..681a63cc15d0 100644 --- a/Packs/GoogleSheets/Integrations/GoogleSheets/GoogleSheets.yml +++ b/Packs/GoogleSheets/Integrations/GoogleSheets/GoogleSheets.yml @@ -665,7 +665,7 @@ script: - contextPath: GoogleSheets.Spreadsheet.updatedSpreadsheet.sheets.title description: Sheet title. type: String - dockerimage: demisto/googleapi-python3:1.0.0.86179 + dockerimage: demisto/googleapi-python3:1.0.0.87804 runonce: false script: "-" subtype: python3 diff --git a/Packs/GoogleSheets/ReleaseNotes/1_0_42.md b/Packs/GoogleSheets/ReleaseNotes/1_0_42.md new file mode 100644 index 000000000000..2648c427c005 --- /dev/null +++ b/Packs/GoogleSheets/ReleaseNotes/1_0_42.md @@ -0,0 +1,3 @@ +#### Integrations +##### Google Sheets +- Updated the Docker image to: *demisto/googleapi-python3:1.0.0.87804*. diff --git a/Packs/GoogleSheets/pack_metadata.json b/Packs/GoogleSheets/pack_metadata.json index 5df81408c64f..f1fcd368506b 100644 --- a/Packs/GoogleSheets/pack_metadata.json +++ b/Packs/GoogleSheets/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Sheets", "description": "The Google Sheets API is a RESTful interface that lets you read and modify a spreadsheet's data. The most common uses of this API include the following tasks- create spreadsheets, read and write spreadsheets cells, update spreadsheet formatting", "support": "xsoar", - "currentVersion": "1.0.41", + "currentVersion": "1.0.42", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From b8c5256890c64bcb6ff7706b5b4ea913dbd28d18 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Tue, 20 Feb 2024 09:07:25 +0200 Subject: [PATCH 032/272] Update Docker Image To demisto/btfl-soup (#33010) * Updated Metadata Of Pack EmailCommunication * Added release notes to pack EmailCommunication * Packs/EmailCommunication/Scripts/DisplayEmailHtmlThread/DisplayEmailHtmlThread.yml Docker image update --- Packs/EmailCommunication/ReleaseNotes/2_0_25.md | 4 ++++ .../Scripts/DisplayEmailHtmlThread/DisplayEmailHtmlThread.yml | 2 +- Packs/EmailCommunication/pack_metadata.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Packs/EmailCommunication/ReleaseNotes/2_0_25.md diff --git a/Packs/EmailCommunication/ReleaseNotes/2_0_25.md b/Packs/EmailCommunication/ReleaseNotes/2_0_25.md new file mode 100644 index 000000000000..f5c98b7a69a6 --- /dev/null +++ b/Packs/EmailCommunication/ReleaseNotes/2_0_25.md @@ -0,0 +1,4 @@ + +#### Scripts +##### DisplayEmailHtmlThread +- Updated the Docker image to: *demisto/btfl-soup:1.0.1.87353*. \ No newline at end of file diff --git a/Packs/EmailCommunication/Scripts/DisplayEmailHtmlThread/DisplayEmailHtmlThread.yml b/Packs/EmailCommunication/Scripts/DisplayEmailHtmlThread/DisplayEmailHtmlThread.yml index ae84113cc0d1..60a9d52bbbda 100644 --- a/Packs/EmailCommunication/Scripts/DisplayEmailHtmlThread/DisplayEmailHtmlThread.yml +++ b/Packs/EmailCommunication/Scripts/DisplayEmailHtmlThread/DisplayEmailHtmlThread.yml @@ -12,7 +12,7 @@ comment: |- enabled: true scripttarget: 0 subtype: python3 -dockerimage: demisto/btfl-soup:1.0.1.84814 +dockerimage: demisto/btfl-soup:1.0.1.87353 runas: DBotWeakRole fromversion: 6.2.0 tests: diff --git a/Packs/EmailCommunication/pack_metadata.json b/Packs/EmailCommunication/pack_metadata.json index 426d51ca0886..8cf8a4722aa4 100644 --- a/Packs/EmailCommunication/pack_metadata.json +++ b/Packs/EmailCommunication/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Email Communication", "description": "Do you have to send multiple emails to end users? This content pack helps you streamline the process and automate updates, notifications and more.\n", "support": "xsoar", - "currentVersion": "2.0.24", + "currentVersion": "2.0.25", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "videos": [ From f5821aec1ebef21ae90600fb50e3a05eb6bd78b9 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:14:29 +0200 Subject: [PATCH 033/272] update docker + RN (#32995) --- .../Integrations/Elasticsearch_v2/Elasticsearch_v2.yml | 2 +- Packs/Elasticsearch/ReleaseNotes/1_3_20.md | 6 ++++++ Packs/Elasticsearch/pack_metadata.json | 2 +- .../Integrations/FeedElasticsearch/FeedElasticsearch.yml | 2 +- Packs/FeedElasticsearch/ReleaseNotes/1_1_4.md | 6 ++++++ Packs/FeedElasticsearch/pack_metadata.json | 2 +- 6 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 Packs/Elasticsearch/ReleaseNotes/1_3_20.md create mode 100644 Packs/FeedElasticsearch/ReleaseNotes/1_1_4.md diff --git a/Packs/Elasticsearch/Integrations/Elasticsearch_v2/Elasticsearch_v2.yml b/Packs/Elasticsearch/Integrations/Elasticsearch_v2/Elasticsearch_v2.yml index b05eaf7bbb15..fba0774cad6b 100644 --- a/Packs/Elasticsearch/Integrations/Elasticsearch_v2/Elasticsearch_v2.yml +++ b/Packs/Elasticsearch/Integrations/Elasticsearch_v2/Elasticsearch_v2.yml @@ -381,7 +381,7 @@ script: description: The result of the index operation. type: string description: Indexes a document into an Elasticsearch index. - dockerimage: demisto/elasticsearch:1.0.0.85878 + dockerimage: demisto/elasticsearch:1.0.0.87483 isfetch: true runonce: false script: '-' diff --git a/Packs/Elasticsearch/ReleaseNotes/1_3_20.md b/Packs/Elasticsearch/ReleaseNotes/1_3_20.md new file mode 100644 index 000000000000..bfda7a04233e --- /dev/null +++ b/Packs/Elasticsearch/ReleaseNotes/1_3_20.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Elasticsearch v2 + +- Updated the Docker image to: *demisto/elasticsearch:1.0.0.87483*. diff --git a/Packs/Elasticsearch/pack_metadata.json b/Packs/Elasticsearch/pack_metadata.json index 8c7de67f71cf..5aa29cd759c7 100644 --- a/Packs/Elasticsearch/pack_metadata.json +++ b/Packs/Elasticsearch/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Elasticsearch", "description": "Search for and analyze data in real time. \n Supports version 6 and later.", "support": "xsoar", - "currentVersion": "1.3.19", + "currentVersion": "1.3.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch.yml b/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch.yml index cd7156ad38a1..4f036fc394ca 100644 --- a/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch.yml +++ b/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch.yml @@ -172,7 +172,7 @@ script: required: true description: Gets indicators available in the configured Elasticsearch database. name: es-get-indicators - dockerimage: demisto/elasticsearch:1.0.0.83352 + dockerimage: demisto/elasticsearch:1.0.0.87483 feed: true runonce: false script: '-' diff --git a/Packs/FeedElasticsearch/ReleaseNotes/1_1_4.md b/Packs/FeedElasticsearch/ReleaseNotes/1_1_4.md new file mode 100644 index 000000000000..9a47e58a0247 --- /dev/null +++ b/Packs/FeedElasticsearch/ReleaseNotes/1_1_4.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Elasticsearch Feed + +- Updated the Docker image to: *demisto/elasticsearch:1.0.0.87483*. diff --git a/Packs/FeedElasticsearch/pack_metadata.json b/Packs/FeedElasticsearch/pack_metadata.json index 39a575efb118..120f74204d14 100644 --- a/Packs/FeedElasticsearch/pack_metadata.json +++ b/Packs/FeedElasticsearch/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Elasticsearch Feed", "description": "Indicators feed from Elasticsearch database", "support": "xsoar", - "currentVersion": "1.1.3", + "currentVersion": "1.1.4", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 4238d8f8ad6908d85f0cb47b7935c6763952a42f Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:15:04 +0200 Subject: [PATCH 034/272] update docker + RN (#32996) --- Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml | 2 +- Packs/GenericSQL/ReleaseNotes/1_1_7.md | 6 ++++++ Packs/GenericSQL/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/GenericSQL/ReleaseNotes/1_1_7.md diff --git a/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml b/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml index 30549611468b..4ddc1ba476d1 100644 --- a/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml +++ b/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml @@ -159,7 +159,7 @@ script: name: bind_variables_values description: Running a sql query name: sql-command - dockerimage: demisto/genericsql:1.1.0.87288 + dockerimage: demisto/genericsql:1.1.0.87817 isfetch: true runonce: false script: '-' diff --git a/Packs/GenericSQL/ReleaseNotes/1_1_7.md b/Packs/GenericSQL/ReleaseNotes/1_1_7.md new file mode 100644 index 000000000000..6deed8d88996 --- /dev/null +++ b/Packs/GenericSQL/ReleaseNotes/1_1_7.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Generic SQL + +- Updated the Docker image to: *demisto/genericsql:1.1.0.87817*. diff --git a/Packs/GenericSQL/pack_metadata.json b/Packs/GenericSQL/pack_metadata.json index 7e800620f6b2..21b7cee151d0 100644 --- a/Packs/GenericSQL/pack_metadata.json +++ b/Packs/GenericSQL/pack_metadata.json @@ -3,7 +3,7 @@ "description": "Connect and execute sql queries in 4 Databases: MySQL, PostgreSQL, Microsoft SQL Server and Oracle", "support": "xsoar", "serverMinVersion": "5.0.0", - "currentVersion": "1.1.6", + "currentVersion": "1.1.7", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 031d0b394f57751551f2681166b178eeebc8e8e2 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:15:39 +0200 Subject: [PATCH 035/272] update docker + RN (#32999) --- Packs/PAN-OS/Integrations/Panorama/Panorama.yml | 2 +- Packs/PAN-OS/ReleaseNotes/2_1_21.md | 6 ++++++ Packs/PAN-OS/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/PAN-OS/ReleaseNotes/2_1_21.md diff --git a/Packs/PAN-OS/Integrations/Panorama/Panorama.yml b/Packs/PAN-OS/Integrations/Panorama/Panorama.yml index 3f06e3bf9f7f..b4f78830a80f 100644 --- a/Packs/PAN-OS/Integrations/Panorama/Panorama.yml +++ b/Packs/PAN-OS/Integrations/Panorama/Panorama.yml @@ -9368,7 +9368,7 @@ script: description: The job ID to use when polling. description: Exports a tech support file (TSF). polling: true - dockerimage: demisto/pan-os-python:1.0.0.85910 + dockerimage: demisto/pan-os-python:1.0.0.87401 isfetch: true runonce: false script: '' diff --git a/Packs/PAN-OS/ReleaseNotes/2_1_21.md b/Packs/PAN-OS/ReleaseNotes/2_1_21.md new file mode 100644 index 000000000000..54e6c97c674b --- /dev/null +++ b/Packs/PAN-OS/ReleaseNotes/2_1_21.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Palo Alto Networks PAN-OS + +- Updated the Docker image to: *demisto/pan-os-python:1.0.0.87401*. diff --git a/Packs/PAN-OS/pack_metadata.json b/Packs/PAN-OS/pack_metadata.json index c1df639e6830..5382494f2859 100644 --- a/Packs/PAN-OS/pack_metadata.json +++ b/Packs/PAN-OS/pack_metadata.json @@ -2,7 +2,7 @@ "name": "PAN-OS by Palo Alto Networks", "description": "Manage Palo Alto Networks Firewall and Panorama. Use this pack to manage Prisma Access through Panorama. For more information see Panorama documentation.", "support": "xsoar", - "currentVersion": "2.1.20", + "currentVersion": "2.1.21", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From b6bd2fb5f120a1766e6e6e30043694f8e98a015d Mon Sep 17 00:00:00 2001 From: samuelFain <65926551+samuelFain@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:34:46 +0200 Subject: [PATCH 036/272] [Okta Event Collector] Add next pagination token logic (#32393) * Update last fetch logic * Implemented 'next' pagination token logic * Handle resetting next_link token * Update release notes * FIxed failing UTs * Remove pragma no cover * Rename 3_2_10.md to 3_2_12.md * add 3_2_10.md * Add UTs * Add UTs --- .../OktaEventCollector/OktaEventCollector.py | 101 ++++++++++++------ .../OktaEventCollector_test.py | 82 ++++++++++++-- Packs/Okta/ReleaseNotes/3_2_12.md | 7 ++ Packs/Okta/pack_metadata.json | 2 +- 4 files changed, 146 insertions(+), 46 deletions(-) create mode 100644 Packs/Okta/ReleaseNotes/3_2_12.md diff --git a/Packs/Okta/Integrations/OktaEventCollector/OktaEventCollector.py b/Packs/Okta/Integrations/OktaEventCollector/OktaEventCollector.py index 3efff82c4949..93a4cb78de37 100644 --- a/Packs/Okta/Integrations/OktaEventCollector/OktaEventCollector.py +++ b/Packs/Okta/Integrations/OktaEventCollector/OktaEventCollector.py @@ -1,6 +1,8 @@ -from CommonServerPython import * from http import HTTPStatus from typing import cast + +from CommonServerPython import * + VENDOR = "okta" PRODUCT = "okta" FETCH_LIMIT = 1000 @@ -16,17 +18,21 @@ def __init__(self, base_url, api_key, verify=True, proxy=False): } super().__init__(base_url=base_url, headers=headers, verify=verify, proxy=proxy) - def get_events(self, since: int, limit: int = FETCH_LIMIT): - params = { - "sortOrder": "ASCENDING", - "since": since, - "limit": limit, - } - return self._http_request(url_suffix='/api/v1/logs', method='GET', headers=self._headers, params=params) + def get_events(self, since: int, limit: int = FETCH_LIMIT, next_link_url: str = ''): + if next_link_url: + return self._http_request(full_url=next_link_url, method='GET', headers=self._headers, resp_type='response') + else: + params = { + "sortOrder": "ASCENDING", + "since": since, + "limit": limit, + } + return self._http_request(url_suffix='/api/v1/logs', method='GET', headers=self._headers, params=params, + resp_type='response') def get_events_command(client: Client, total_events_to_fetch, since, - last_object_ids: List[str] = None) -> tuple[List[dict], int]: # pragma: no cover + last_object_ids: list[str] = [], next_link: str = '') -> tuple[list[dict], int, str]: """ Fetches events from the okta api until the total_events_to_fetch is reached or no more events are available. if 429:TOO_MANY_REQUESTS is returned, will return the stored_events so far and the x-rate-limit-reset @@ -44,24 +50,35 @@ def get_events_command(client: Client, total_events_to_fetch, since, stored_events: list = [] num_of_events_to_fetch = FETCH_LIMIT if total_events_to_fetch > FETCH_LIMIT else total_events_to_fetch demisto.debug(f"num of events to fetch: {num_of_events_to_fetch} since: {since}") - while len(stored_events) < total_events_to_fetch: + should_continue = True + while len(stored_events) < total_events_to_fetch and should_continue: demisto.debug(f"stored_events collected: {len(stored_events)}") try: - events = client.get_events(since=since, limit=num_of_events_to_fetch) # type: ignore - if events: + if next_link: + demisto.debug("Running get_events using next_link") + response = client.get_events(since=since, limit=num_of_events_to_fetch, next_link_url=next_link) # type: ignore + else: + demisto.debug("Running get_events using since") + response = client.get_events(since=since, limit=num_of_events_to_fetch) # type: ignore + + if events := json.loads(response.text): demisto.debug(f'received {len(events)} number of events.') + if len(events) < num_of_events_to_fetch: + demisto.debug(f"Number of events collected is smaller than: {num_of_events_to_fetch} \ + will stop after current fetch.") + should_continue = False since = events[-1]['published'] if last_object_ids: events = remove_duplicates(events, last_object_ids) # type: ignore + demisto.debug(f'Number of events after dedup {len(events)}') if not events: - demisto.debug('Events are empty after dedup will break.') + demisto.debug('Events are empty after dedup - will break. Resetting next_link token.') + next_link = '' break stored_events.extend(events) - if len(events) < num_of_events_to_fetch: - demisto.debug(f"Number of events collected is smaller than: {num_of_events_to_fetch} will break.") - break else: - demisto.debug('Didnt receive any events from the api.') + demisto.debug('Didnt receive any events from the api. Resetting next_link token.') + next_link = '' break except DemistoException as exc: msg = f'something went wrong: {exc}' @@ -74,14 +91,22 @@ def get_events_command(client: Client, total_events_to_fetch, since, demisto.debug(f'fetch-events Got 429. okta rate limit headers:\n \ x-rate-limit-remaining: {res.headers["x-rate-limit-remaining"]}\n \ x-rate-limit-reset: {res.headers["x-rate-limit-reset"]}\n') - return stored_events, int(res.headers['x-rate-limit-reset']) - return stored_events, 0 + return stored_events, int(res.headers['x-rate-limit-reset']), next_link + return stored_events, 0, next_link except Exception as exc: demisto.error(f'Unexpected error.\n{traceback.format_exc()}') if len(stored_events) == 0: raise exc - return stored_events, 0 - return stored_events, 0 + return stored_events, 0, next_link + + if url := response.links.get('next'): + next_link = url.get('url') + demisto.debug("next next_link url found and set as current next_link") + else: + next_link = '' + demisto.debug("next_link set to empty value") + + return stored_events, 0, next_link def remove_duplicates(events: list, ids: list) -> list: @@ -91,9 +116,13 @@ def remove_duplicates(events: list, ids: list) -> list: return [event for event in events if event['uuid'] not in ids] -def get_last_run(events: List[dict], last_run_after) -> dict: +def get_last_run(events: List[dict], last_run_after, next_link) -> dict: """ - Get the info from the last run, it returns the time to query from and a list of ids to prevent duplications + Build the last_run dictionary for the next fetch: + it returns 3 keys: + - after: the time to query from. + - ids: a list of ids to prevent duplications. + - next_link: a string representing the next request link if available, or an empty string if not. """ ids = [] # gets the last event time @@ -103,19 +132,21 @@ def get_last_run(events: List[dict], last_run_after) -> dict: break ids.append(event.get('uuid')) last_time = datetime.strptime(str(last_time).lower().replace('z', ''), '%Y-%m-%dt%H:%M:%S.%f') - return {'after': last_time.isoformat(), 'ids': ids} + return {'after': last_time.isoformat(), 'ids': ids, 'next_link': next_link} def fetch_events(client: Client, start_time_epoch: int, events_limit: int, last_run_after, - last_object_ids: List[str] = None) -> List[dict]: # pragma: no cover + last_object_ids: list[str] = [], + next_link: str = '') -> tuple[list[dict], str]: while True: - events, epoch_time_to_continue_fetch = get_events_command(client=client, - total_events_to_fetch=events_limit, - since=last_run_after, - last_object_ids=last_object_ids) + events, epoch_time_to_continue_fetch, next_link = get_events_command(client=client, + total_events_to_fetch=events_limit, + since=last_run_after, + last_object_ids=last_object_ids, + next_link=next_link) if epoch_time_to_continue_fetch == 0: break @@ -126,7 +157,7 @@ def fetch_events(client: Client, time.sleep(sleep_time) # pylint: disable=E9003 else: break - return events + return events, next_link def main(): # pragma: no cover @@ -150,7 +181,7 @@ def main(): # pragma: no cover if command == 'okta-get-events': after = cast(datetime, dateparser.parse(demisto_args.get('from_date').strip())) - events, _ = get_events_command(client, events_limit, since=after.isoformat()) + events, _, _ = get_events_command(client, events_limit, since=after.isoformat()) command_results = CommandResults( readable_output=tableToMarkdown('Okta Logs', events, headerTransform=pascalToSpace), raw_response=events, @@ -164,15 +195,17 @@ def main(): # pragma: no cover after = cast(datetime, dateparser.parse(demisto_params['after'].strip())) last_run = demisto.getLastRun() last_object_ids = last_run.get('ids') + next_link = last_run.get('next_link') if 'after' not in last_run: last_run_after = after.isoformat() # type: ignore else: last_run_after = last_run['after'] - events = fetch_events(client, start_time_epoch, events_limit, - last_run_after=last_run_after, last_object_ids=last_object_ids) + demisto.debug(f'{last_run=}') + events, next_link = fetch_events(client, start_time_epoch, events_limit, + last_run_after=last_run_after, last_object_ids=last_object_ids, next_link=next_link) demisto.debug(f'sending_events_to_xsiam: {len(events)}') send_events_to_xsiam(events[:events_limit], vendor=VENDOR, product=PRODUCT) - demisto.setLastRun(get_last_run(events, last_run_after)) + demisto.setLastRun(get_last_run(events, last_run_after, next_link)) except Exception as e: return_error(f'Failed to execute {demisto.command()} command. Error: {str(e)}') diff --git a/Packs/Okta/Integrations/OktaEventCollector/OktaEventCollector_test.py b/Packs/Okta/Integrations/OktaEventCollector/OktaEventCollector_test.py index 99c6edb77a02..da96791f0dfe 100644 --- a/Packs/Okta/Integrations/OktaEventCollector/OktaEventCollector_test.py +++ b/Packs/Okta/Integrations/OktaEventCollector/OktaEventCollector_test.py @@ -1,13 +1,25 @@ -from OktaEventCollector import Client, remove_duplicates, get_last_run, get_events_command, main -import pytest from unittest.mock import MagicMock + +import pytest from freezegun import freeze_time +from OktaEventCollector import Client, DemistoException, fetch_events, get_events_command, get_last_run, main, remove_duplicates + import demistomock as demisto -id1_pub = [[{'uuid': 'a5b57ec5feaa', 'published': '2022-04-17T12:32:36.667'}]] + +class MockResponse: + def __init__(self, data=None, text='', status_code=200, links={}): + self.data = data + self.text = str(data) if data else text + self.status_code = status_code + self.links = links + + +id1_pub = '[{"uuid": "a5b57ec5feaa", "published": "2022-04-17T12:32:36.667"}]' id2_pub = [{'uuid': 'a5b57ec5febb', 'published': '2022-04-17T12:32:36.667'}] id3_pub = [{'uuid': 'a5b57ec5fecc', 'published': '2022-04-17T12:32:36.667'}] id4_pub = [{'uuid': 'a5b57ec5fedd', 'published': '2022-04-17T12:32:36.667'}] +empty_response = '[]' id1 = {'uuid': 'a5b57ec5febb'} id2 = {'uuid': 'a5b57ec5fecc'} @@ -46,7 +58,7 @@ def test_remove_duplicates(events, ids, result): {'published': '2022-04-17T12:33:36.667', 'uuid': '1d0844b6-3148-11ec-9027-a5b57ec5fccc'}], '2022-04-17T11:30:00.000', - {'after': '2022-04-17T12:33:36.667000', 'ids': ['1d0844b6-3148-11ec-9027-a5b57ec5fccc']}), + {'after': '2022-04-17T12:33:36.667000', 'ids': ['1d0844b6-3148-11ec-9027-a5b57ec5fccc'], 'next_link': ''}), ([{'published': '2022-04-17T12:31:36.667', 'uuid': '1d0844b6-3148-11ec-9027-a5b57ec5faaa'}, {'published': '2022-04-17T12:32:36.667', @@ -56,12 +68,12 @@ def test_remove_duplicates(events, ids, result): '2022-04-17T11:30:00.000', {'after': '2022-04-17T12:32:36.667000', 'ids': ['1d0844b6-3148-11ec-9027-a5b57ec5fccc', - '1d0844b6-3148-11ec-9027-a5b57ec5fbbb']}), + '1d0844b6-3148-11ec-9027-a5b57ec5fbbb'], 'next_link': ''}), ([], '2022-04-17T12:31:36.667', - {'after': '2022-04-17T12:31:36.667000', 'ids': []})]) + {'after': '2022-04-17T12:31:36.667000', 'ids': [], 'next_link': ''})]) def test_get_last_run(events, last_run_after, result): - assert get_last_run(events, last_run_after) == result + assert get_last_run(events, last_run_after, next_link='') == result def test_get_events_success(dummy_client, mocker): @@ -69,19 +81,67 @@ def test_get_events_success(dummy_client, mocker): mock_remove_duplicates.return_value = [{'id': 1, 'published': '2022-04-17T12:32:36.667'}] mocker.patch('OktaEventCollector.remove_duplicates', mock_remove_duplicates) - mocker.patch.object(dummy_client, 'get_events', side_effect=id1_pub) - events, epoch = get_events_command(dummy_client, 1, 'since', ['id1']) + mocker.patch.object(dummy_client, 'get_events', side_effect=[MockResponse(text=id1_pub)]) + events, epoch, _ = get_events_command(dummy_client, 1, 'since', ['id1']) assert len(events) == 1 assert epoch == 0 +def test_get_events_with_next_link_success(dummy_client, mocker): + mock_remove_duplicates = MagicMock() + mock_remove_duplicates.return_value = [{'id': 1, + 'published': '2022-04-17T12:32:36.667'}] + mocker.patch('OktaEventCollector.remove_duplicates', mock_remove_duplicates) + mocker.patch.object(dummy_client, 'get_events', side_effect=[ + MockResponse(text=id1_pub, links={'next': {'url': 'next_link'}})]) + events, epoch, next_link = get_events_command(dummy_client, 1, 'since', ['id1'], next_link='next_link') + assert len(events) == 1 + assert epoch == 0 + assert next_link == 'next_link' + + def test_get_events_no_events(dummy_client, mocker): - mocker.patch.object(dummy_client, 'get_events', return_value=None) - events, epoch = get_events_command(dummy_client, 1, 'since') + mocker.patch.object(dummy_client, 'get_events', side_effect=[MockResponse(text=empty_response)]) + events, epoch, _ = get_events_command(dummy_client, 1, 'since') assert len(events) == 0 assert epoch == 0 +def test_get_events_429_error_failure(dummy_client, mocker): + mock_remove_duplicates = MagicMock() + mock_remove_duplicates.return_value = [{'id': 1, + 'published': '2022-04-17T12:32:36.667'}] + mocker.patch('OktaEventCollector.remove_duplicates', mock_remove_duplicates) + mocker.patch.object(dummy_client, 'get_events', side_effect=[DemistoException('exception')]) + with pytest.raises(DemistoException): + get_events_command(dummy_client, 1, 'since', ['id1']) + + +def test_get_events_general_failure(dummy_client, mocker): + mock_remove_duplicates = MagicMock() + mock_remove_duplicates.return_value = [{'id': 1, + 'published': '2022-04-17T12:32:36.667'}] + mocker.patch('OktaEventCollector.remove_duplicates', mock_remove_duplicates) + mocker.patch.object(dummy_client, 'get_events', side_effect=BaseException()) + with pytest.raises(BaseException): + get_events_command(dummy_client, 1, 'since', ['id1']) + + +def test_fetch_event(dummy_client, mocker): + response = { + 'events': [{'id': 1, 'published': '2022-04-17T12:32:36.667'}], + 'epoch_time_to_continue_fetch': 0, + 'next_link': 'next_link' + } + mocker.patch('OktaEventCollector.get_events_command', side_effect=[ + ([], 1, response['next_link']), + (response['events'], response['epoch_time_to_continue_fetch'], response['next_link']), + ]) + events, next_link = fetch_events(dummy_client, 0, 1, '') + assert events == [{'id': 1, 'published': '2022-04-17T12:32:36.667'}] + assert next_link == 'next_link' + + @freeze_time('2022-04-17T12:32:36.667Z') def test_429_too_many_requests(mocker, requests_mock): diff --git a/Packs/Okta/ReleaseNotes/3_2_12.md b/Packs/Okta/ReleaseNotes/3_2_12.md new file mode 100644 index 000000000000..8133974cf635 --- /dev/null +++ b/Packs/Okta/ReleaseNotes/3_2_12.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Okta Event Collector + +- Fixed an issue where the same events were fetched repeatedly instead of progressing to the next set of events. +- Added support for token based pagination while fetching. diff --git a/Packs/Okta/pack_metadata.json b/Packs/Okta/pack_metadata.json index 74bd96b59ff7..56d073a9bacb 100644 --- a/Packs/Okta/pack_metadata.json +++ b/Packs/Okta/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Okta", "description": "Integration with Okta's cloud-based identity management service.", "support": "xsoar", - "currentVersion": "3.2.11", + "currentVersion": "3.2.12", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 7704e82ecc4628632f46f450a1cae23a6b83a6d2 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:07:14 +0200 Subject: [PATCH 037/272] Update `demisto/sklearn` 0-10 coverage rate (#32760) * upgrade images * update RN * Bump pack from version Base to 1.33.26. * Bump pack from version Base to 1.33.27. * Bump pack from version Base to 1.33.28. * Bump pack from version Base to 1.33.29. * Bump pack from version Base to 1.33.30. * Bump pack from version Base to 1.33.31. * Bump pack from version Base to 1.33.32. * Bump pack from version Base to 1.33.33. * Bump pack from version Base to 1.33.34. --------- Co-authored-by: Content Bot --- Packs/Base/ReleaseNotes/1_33_34.md | 6 ++++++ .../DrawRelatedIncidentsCanvas.yml | 2 +- Packs/Base/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/Base/ReleaseNotes/1_33_34.md diff --git a/Packs/Base/ReleaseNotes/1_33_34.md b/Packs/Base/ReleaseNotes/1_33_34.md new file mode 100644 index 000000000000..a2279792e8d2 --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_33_34.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### DrawRelatedIncidentsCanvas + +- Updated the Docker image to: *demisto/sklearn:1.0.0.86554*. diff --git a/Packs/Base/Scripts/DrawRelatedIncidentsCanvas/DrawRelatedIncidentsCanvas.yml b/Packs/Base/Scripts/DrawRelatedIncidentsCanvas/DrawRelatedIncidentsCanvas.yml index 7bc75ecff922..8ae465269b6a 100644 --- a/Packs/Base/Scripts/DrawRelatedIncidentsCanvas/DrawRelatedIncidentsCanvas.yml +++ b/Packs/Base/Scripts/DrawRelatedIncidentsCanvas/DrawRelatedIncidentsCanvas.yml @@ -34,7 +34,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/sklearn:1.0.0.49796 +dockerimage: demisto/sklearn:1.0.0.86554 runas: DBotWeakRole tests: - No tests (auto formatted) diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index 626f953c6d96..6b58869f6b55 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.33.33", + "currentVersion": "1.33.34", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", From d629084f8fbe62dd16cdb1ccff1780ac3dfeac34 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:07:27 +0200 Subject: [PATCH 038/272] Update `demisto/tidy` 0-10 coverage rate (#32671) * upgrade images * update RN --- Packs/Tidy/Integrations/Tidy/Tidy.yml | 2 +- Packs/Tidy/ReleaseNotes/1_0_11.md | 6 ++++++ Packs/Tidy/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/Tidy/ReleaseNotes/1_0_11.md diff --git a/Packs/Tidy/Integrations/Tidy/Tidy.yml b/Packs/Tidy/Integrations/Tidy/Tidy.yml index 9aad4805d6d8..28355e7e456f 100644 --- a/Packs/Tidy/Integrations/Tidy/Tidy.yml +++ b/Packs/Tidy/Integrations/Tidy/Tidy.yml @@ -602,7 +602,7 @@ script: - arguments: [] description: Install python environment. name: tidy-python-env - dockerimage: demisto/tidy:1.0.0.62989 + dockerimage: demisto/tidy:1.0.0.86483 script: '' subtype: python3 type: python diff --git a/Packs/Tidy/ReleaseNotes/1_0_11.md b/Packs/Tidy/ReleaseNotes/1_0_11.md new file mode 100644 index 000000000000..acc8945e364b --- /dev/null +++ b/Packs/Tidy/ReleaseNotes/1_0_11.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Tidy + +- Updated the Docker image to: *demisto/tidy:1.0.0.86483*. diff --git a/Packs/Tidy/pack_metadata.json b/Packs/Tidy/pack_metadata.json index dbe518119cc6..7e3a4d22f03f 100644 --- a/Packs/Tidy/pack_metadata.json +++ b/Packs/Tidy/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Tidy", "description": "Tidy integration handle endpoints environment installation.", "support": "xsoar", - "currentVersion": "1.0.10", + "currentVersion": "1.0.11", "author": "Cortex XSOAR", "url": "", "email": "https://www.paloaltonetworks.com/cortex", From 6bb49be5f038deb37540c3a04cad70d198e6207f Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:10:52 +0200 Subject: [PATCH 039/272] Update `demisto/snowflake` 0-10 coverage rate (#32667) * upgrade images * update RN --- Packs/Snowflake/Integrations/Snowflake/Snowflake.yml | 2 +- Packs/Snowflake/ReleaseNotes/1_0_4.md | 6 ++++++ Packs/Snowflake/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/Snowflake/ReleaseNotes/1_0_4.md diff --git a/Packs/Snowflake/Integrations/Snowflake/Snowflake.yml b/Packs/Snowflake/Integrations/Snowflake/Snowflake.yml index adc66ebc478e..b81eeae7cc51 100644 --- a/Packs/Snowflake/Integrations/Snowflake/Snowflake.yml +++ b/Packs/Snowflake/Integrations/Snowflake/Snowflake.yml @@ -129,7 +129,7 @@ script: description: Makes a DML change in the database. execution: true name: snowflake-update - dockerimage: demisto/snowflake:1.0.0.2505 + dockerimage: demisto/snowflake:1.0.0.86257 isfetch: true script: '-' type: python diff --git a/Packs/Snowflake/ReleaseNotes/1_0_4.md b/Packs/Snowflake/ReleaseNotes/1_0_4.md new file mode 100644 index 000000000000..f08c2a458a0e --- /dev/null +++ b/Packs/Snowflake/ReleaseNotes/1_0_4.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Snowflake + +- Updated the Docker image to: *demisto/snowflake:1.0.0.86257*. diff --git a/Packs/Snowflake/pack_metadata.json b/Packs/Snowflake/pack_metadata.json index 6dff2027bf7c..b2a82de18398 100644 --- a/Packs/Snowflake/pack_metadata.json +++ b/Packs/Snowflake/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Snowflake", "description": "Analytic data warehouse provided as Software-as-a-Service.", "support": "xsoar", - "currentVersion": "1.0.3", + "currentVersion": "1.0.4", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e18959d8e985a3bada2f107814b4141a3d880a52 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:11:50 +0200 Subject: [PATCH 040/272] Update `demisto/smbprotocol` 0-10 coverage rate (#32666) * upgrade images * update RN --- Packs/SMB/Integrations/SMB_v2/SMB_v2.yml | 2 +- Packs/SMB/ReleaseNotes/2_0_17.md | 6 ++++++ Packs/SMB/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/SMB/ReleaseNotes/2_0_17.md diff --git a/Packs/SMB/Integrations/SMB_v2/SMB_v2.yml b/Packs/SMB/Integrations/SMB_v2/SMB_v2.yml index 6c612106df61..e100617452fe 100644 --- a/Packs/SMB/Integrations/SMB_v2/SMB_v2.yml +++ b/Packs/SMB/Integrations/SMB_v2/SMB_v2.yml @@ -162,7 +162,7 @@ script: - name: password description: The password to use for authentication. If empty, the password from the instance configuration is used. description: Removes a directory from the given path. - dockerimage: demisto/smbprotocol:1.0.0.63639 + dockerimage: demisto/smbprotocol:1.0.0.85835 runonce: false script: '-' type: python diff --git a/Packs/SMB/ReleaseNotes/2_0_17.md b/Packs/SMB/ReleaseNotes/2_0_17.md new file mode 100644 index 000000000000..c2d0a413059e --- /dev/null +++ b/Packs/SMB/ReleaseNotes/2_0_17.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Server Message Block (SMB) v2 + +- Updated the Docker image to: *demisto/smbprotocol:1.0.0.85835*. diff --git a/Packs/SMB/pack_metadata.json b/Packs/SMB/pack_metadata.json index c8d8de223c58..2a1a0e480e54 100644 --- a/Packs/SMB/pack_metadata.json +++ b/Packs/SMB/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Server Message Block (SMB)", "description": "File exchange with an SMB server.", "support": "xsoar", - "currentVersion": "2.0.16", + "currentVersion": "2.0.17", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 779e49ab085e1fd565b7e2b3de9864014002b77c Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:12:07 +0200 Subject: [PATCH 041/272] Update `demisto/resilient` 10-25 coverage rate (#32659) * upgrade images * update RN --- .../IBMResilientSystems/IBMResilientSystems.yml | 2 +- Packs/IBMResilientSystems/ReleaseNotes/1_1_9.md | 6 ++++++ Packs/IBMResilientSystems/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/IBMResilientSystems/ReleaseNotes/1_1_9.md diff --git a/Packs/IBMResilientSystems/Integrations/IBMResilientSystems/IBMResilientSystems.yml b/Packs/IBMResilientSystems/Integrations/IBMResilientSystems/IBMResilientSystems.yml index 148a20d779bc..afbced834f40 100644 --- a/Packs/IBMResilientSystems/Integrations/IBMResilientSystems/IBMResilientSystems.yml +++ b/Packs/IBMResilientSystems/Integrations/IBMResilientSystems/IBMResilientSystems.yml @@ -735,7 +735,7 @@ script: - contextPath: Resilient.IncidentArtifact.ip.destination description: Whether the IP address is a destination. type: Boolean - dockerimage: demisto/resilient:2.0.0.45701 + dockerimage: demisto/resilient:2.0.0.86430 isfetch: true runonce: false script: '-' diff --git a/Packs/IBMResilientSystems/ReleaseNotes/1_1_9.md b/Packs/IBMResilientSystems/ReleaseNotes/1_1_9.md new file mode 100644 index 000000000000..c58dc6b826e4 --- /dev/null +++ b/Packs/IBMResilientSystems/ReleaseNotes/1_1_9.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### IBM Resilient Systems + +- Updated the Docker image to: *demisto/resilient:2.0.0.86430*. diff --git a/Packs/IBMResilientSystems/pack_metadata.json b/Packs/IBMResilientSystems/pack_metadata.json index 40e58672f8aa..a3425be46475 100644 --- a/Packs/IBMResilientSystems/pack_metadata.json +++ b/Packs/IBMResilientSystems/pack_metadata.json @@ -2,7 +2,7 @@ "name": "IBM Resilient Systems", "description": "Case management that enables visibility across your tools for continual IR improvement", "support": "xsoar", - "currentVersion": "1.1.8", + "currentVersion": "1.1.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 618091097b2a3c86f9cd280a39ec1184f242eb55 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:12:36 +0200 Subject: [PATCH 042/272] Update `demisto/google-vision-api` 0-10 coverage rate (#32658) * upgrade images * update RN --- .../Integrations/GoogleVisionAPI/GoogleVisionAPI.yml | 2 +- Packs/GoogleVisionAPI/ReleaseNotes/1_0_21.md | 6 ++++++ Packs/GoogleVisionAPI/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/GoogleVisionAPI/ReleaseNotes/1_0_21.md diff --git a/Packs/GoogleVisionAPI/Integrations/GoogleVisionAPI/GoogleVisionAPI.yml b/Packs/GoogleVisionAPI/Integrations/GoogleVisionAPI/GoogleVisionAPI.yml index 663f50338387..2232a7f6aa6a 100644 --- a/Packs/GoogleVisionAPI/Integrations/GoogleVisionAPI/GoogleVisionAPI.yml +++ b/Packs/GoogleVisionAPI/Integrations/GoogleVisionAPI/GoogleVisionAPI.yml @@ -44,7 +44,7 @@ script: - contextPath: GoogleVisionAPI.Logo.Score description: The certainty score provided by the Google Vision API. type: Unknown - dockerimage: demisto/google-vision-api:1.0.0.63870 + dockerimage: demisto/google-vision-api:1.0.0.86505 runonce: false script: '-' type: python diff --git a/Packs/GoogleVisionAPI/ReleaseNotes/1_0_21.md b/Packs/GoogleVisionAPI/ReleaseNotes/1_0_21.md new file mode 100644 index 000000000000..852ec08609a6 --- /dev/null +++ b/Packs/GoogleVisionAPI/ReleaseNotes/1_0_21.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Google Vision AI + +- Updated the Docker image to: *demisto/google-vision-api:1.0.0.86505*. diff --git a/Packs/GoogleVisionAPI/pack_metadata.json b/Packs/GoogleVisionAPI/pack_metadata.json index 76cefd59ae05..c4445a6e072f 100644 --- a/Packs/GoogleVisionAPI/pack_metadata.json +++ b/Packs/GoogleVisionAPI/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Vision AI", "description": "Image processing with Google Vision API", "support": "xsoar", - "currentVersion": "1.0.20", + "currentVersion": "1.0.21", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 9064b4d62061884571c953786f9898a82102de8f Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:12:55 +0200 Subject: [PATCH 043/272] Update `demisto/google-kms` 10-25 coverage rate (#32656) * upgrade images * update RN --- .../GoogleKeyManagementService.yml | 2 +- Packs/GoogleKeyManagementService/ReleaseNotes/1_0_22.md | 6 ++++++ Packs/GoogleKeyManagementService/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/GoogleKeyManagementService/ReleaseNotes/1_0_22.md diff --git a/Packs/GoogleKeyManagementService/Integrations/GoogleKeyManagementService/GoogleKeyManagementService.yml b/Packs/GoogleKeyManagementService/Integrations/GoogleKeyManagementService/GoogleKeyManagementService.yml index a76d5304f41a..9126065d289b 100644 --- a/Packs/GoogleKeyManagementService/Integrations/GoogleKeyManagementService/GoogleKeyManagementService.yml +++ b/Packs/GoogleKeyManagementService/Integrations/GoogleKeyManagementService/GoogleKeyManagementService.yml @@ -1237,7 +1237,7 @@ script: - contextPath: GoogleKMS.PublicKey.Algorithm description: The algorithm used in the CryptoKey type: String - dockerimage: demisto/google-kms:1.0.0.62005 + dockerimage: demisto/google-kms:1.0.0.86683 runonce: false script: '-' type: python diff --git a/Packs/GoogleKeyManagementService/ReleaseNotes/1_0_22.md b/Packs/GoogleKeyManagementService/ReleaseNotes/1_0_22.md new file mode 100644 index 000000000000..3d8cbe64bdb2 --- /dev/null +++ b/Packs/GoogleKeyManagementService/ReleaseNotes/1_0_22.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Google Key Management Service + +- Updated the Docker image to: *demisto/google-kms:1.0.0.86683*. diff --git a/Packs/GoogleKeyManagementService/pack_metadata.json b/Packs/GoogleKeyManagementService/pack_metadata.json index 775b0e74854a..463c9f8898e9 100644 --- a/Packs/GoogleKeyManagementService/pack_metadata.json +++ b/Packs/GoogleKeyManagementService/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Key Management Service", "description": "Use the Google Key Management Service API for CryptoKey management and encrypt/decrypt functionality.", "support": "xsoar", - "currentVersion": "1.0.21", + "currentVersion": "1.0.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e84d7dd4ea570ee9040bc06925cfd36c3c75b67c Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:13:14 +0200 Subject: [PATCH 044/272] Update `demisto/google-cloud-translate` 25-40 coverage rate (#32655) * upgrade images * update RN --- .../GoogleCloudTranslate/GoogleCloudTranslate.yml | 2 +- Packs/GoogleCloudTranslate/ReleaseNotes/1_0_9.md | 6 ++++++ Packs/GoogleCloudTranslate/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/GoogleCloudTranslate/ReleaseNotes/1_0_9.md diff --git a/Packs/GoogleCloudTranslate/Integrations/GoogleCloudTranslate/GoogleCloudTranslate.yml b/Packs/GoogleCloudTranslate/Integrations/GoogleCloudTranslate/GoogleCloudTranslate.yml index 259ff2791485..109106233a03 100644 --- a/Packs/GoogleCloudTranslate/Integrations/GoogleCloudTranslate/GoogleCloudTranslate.yml +++ b/Packs/GoogleCloudTranslate/Integrations/GoogleCloudTranslate/GoogleCloudTranslate.yml @@ -67,7 +67,7 @@ script: - contextPath: GoogleCloudTranslate.TranslateText.translated_text description: The translated text. type: String - dockerimage: demisto/google-cloud-translate:1.0.0.63615 + dockerimage: demisto/google-cloud-translate:1.0.0.85793 runonce: false script: '-' type: python diff --git a/Packs/GoogleCloudTranslate/ReleaseNotes/1_0_9.md b/Packs/GoogleCloudTranslate/ReleaseNotes/1_0_9.md new file mode 100644 index 000000000000..e6412af84378 --- /dev/null +++ b/Packs/GoogleCloudTranslate/ReleaseNotes/1_0_9.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Google Cloud Translate + +- Updated the Docker image to: *demisto/google-cloud-translate:1.0.0.85793*. diff --git a/Packs/GoogleCloudTranslate/pack_metadata.json b/Packs/GoogleCloudTranslate/pack_metadata.json index 7509bb28e024..852842948f69 100644 --- a/Packs/GoogleCloudTranslate/pack_metadata.json +++ b/Packs/GoogleCloudTranslate/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Google Cloud Translate", "description": "A Google API cloud based translation service.", "support": "xsoar", - "currentVersion": "1.0.8", + "currentVersion": "1.0.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 40d91ade0d37e71bb907e1557cccc30f324d44b4 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:13:31 +0200 Subject: [PATCH 045/272] Update `demisto/pwsh-exchangev3` 0-10 coverage rate (#32654) * upgrade images * update RN * Bump pack from version Microsoft365Defender to 4.5.18. * Bump pack from version Microsoft365Defender to 4.5.19. --------- Co-authored-by: Content Bot --- .../O365DefenderSafeLinks/O365DefenderSafeLinks.yml | 2 +- Packs/Microsoft365Defender/ReleaseNotes/4_5_19.md | 6 ++++++ Packs/Microsoft365Defender/pack_metadata.json | 2 +- .../MicrosoftPolicyAndComplianceAuditLog.yml | 2 +- Packs/Office365AndAzureAuditLog/ReleaseNotes/2_0_1.md | 6 ++++++ Packs/Office365AndAzureAuditLog/pack_metadata.json | 2 +- 6 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 Packs/Microsoft365Defender/ReleaseNotes/4_5_19.md create mode 100644 Packs/Office365AndAzureAuditLog/ReleaseNotes/2_0_1.md diff --git a/Packs/Microsoft365Defender/Integrations/O365DefenderSafeLinks/O365DefenderSafeLinks.yml b/Packs/Microsoft365Defender/Integrations/O365DefenderSafeLinks/O365DefenderSafeLinks.yml index 71c9ef1617be..d6aec1ab30e1 100644 --- a/Packs/Microsoft365Defender/Integrations/O365DefenderSafeLinks/O365DefenderSafeLinks.yml +++ b/Packs/Microsoft365Defender/Integrations/O365DefenderSafeLinks/O365DefenderSafeLinks.yml @@ -939,7 +939,7 @@ script: runonce: false script: "-" type: powershell - dockerimage: demisto/pwsh-exchangev3:1.0.0.49863 + dockerimage: demisto/pwsh-exchangev3:1.0.0.80547 fromversion: 6.0.0 tests: - No Test diff --git a/Packs/Microsoft365Defender/ReleaseNotes/4_5_19.md b/Packs/Microsoft365Defender/ReleaseNotes/4_5_19.md new file mode 100644 index 000000000000..cc43c24909a4 --- /dev/null +++ b/Packs/Microsoft365Defender/ReleaseNotes/4_5_19.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### O365 Defender SafeLinks + +- Updated the Docker image to: *demisto/pwsh-exchangev3:1.0.0.80547*. diff --git a/Packs/Microsoft365Defender/pack_metadata.json b/Packs/Microsoft365Defender/pack_metadata.json index fca1264e5ef1..8589ef24ce1d 100644 --- a/Packs/Microsoft365Defender/pack_metadata.json +++ b/Packs/Microsoft365Defender/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft 365 Defender", "description": "Microsoft 365 Defender is a unified pre- and post-breach enterprise defense suite that natively coordinates detection, prevention, investigation, and response across endpoints, identities, email, and applications to provide integrated protection against sophisticated attacks.", "support": "xsoar", - "currentVersion": "4.5.18", + "currentVersion": "4.5.19", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Office365AndAzureAuditLog/Integrations/MicrosoftPolicyAndComplianceAuditLog/MicrosoftPolicyAndComplianceAuditLog.yml b/Packs/Office365AndAzureAuditLog/Integrations/MicrosoftPolicyAndComplianceAuditLog/MicrosoftPolicyAndComplianceAuditLog.yml index 53563019c7c5..4e44fba622fa 100644 --- a/Packs/Office365AndAzureAuditLog/Integrations/MicrosoftPolicyAndComplianceAuditLog/MicrosoftPolicyAndComplianceAuditLog.yml +++ b/Packs/Office365AndAzureAuditLog/Integrations/MicrosoftPolicyAndComplianceAuditLog/MicrosoftPolicyAndComplianceAuditLog.yml @@ -153,7 +153,7 @@ script: runonce: false script: '-' type: powershell - dockerimage: demisto/pwsh-exchangev3:1.0.0.49863 + dockerimage: demisto/pwsh-exchangev3:1.0.0.80547 fromversion: 5.5.0 tests: - Audit Log - Test diff --git a/Packs/Office365AndAzureAuditLog/ReleaseNotes/2_0_1.md b/Packs/Office365AndAzureAuditLog/ReleaseNotes/2_0_1.md new file mode 100644 index 000000000000..7dbac10e9bdb --- /dev/null +++ b/Packs/Office365AndAzureAuditLog/ReleaseNotes/2_0_1.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Policy And Compliance (Audit Log) + +- Updated the Docker image to: *demisto/pwsh-exchangev3:1.0.0.80547*. diff --git a/Packs/Office365AndAzureAuditLog/pack_metadata.json b/Packs/Office365AndAzureAuditLog/pack_metadata.json index 14e1778f3a67..2d88e4397a19 100644 --- a/Packs/Office365AndAzureAuditLog/pack_metadata.json +++ b/Packs/Office365AndAzureAuditLog/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Office 365 and Azure (Audit Log)", "description": "Search the unified audit log to view user and administrator activity in your organization.", "support": "xsoar", - "currentVersion": "2.0.0", + "currentVersion": "2.0.1", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 855006624828326102547289917e08104afcb7eb Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:35:46 +0200 Subject: [PATCH 046/272] Update `demisto/fastapi` 25-40 coverage rate (#32572) * upgrade images * update RN --- .../GitHubEventCollector/GitHubEventCollector.yml | 2 +- Packs/GitHub/ReleaseNotes/2_0_28.md | 6 ++++++ Packs/GitHub/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/GitHub/ReleaseNotes/2_0_28.md diff --git a/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.yml b/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.yml index 8d7de56bb25c..ad9785c08631 100644 --- a/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.yml +++ b/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.yml @@ -73,7 +73,7 @@ script: required: true description: Manual command to fetch events and display them. name: github-get-events - dockerimage: demisto/fastapi:1.0.0.64474 + dockerimage: demisto/fastapi:1.0.0.86524 isfetchevents: true subtype: python3 marketplaces: diff --git a/Packs/GitHub/ReleaseNotes/2_0_28.md b/Packs/GitHub/ReleaseNotes/2_0_28.md new file mode 100644 index 000000000000..f76d312ace88 --- /dev/null +++ b/Packs/GitHub/ReleaseNotes/2_0_28.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Github Event Collector + +- Updated the Docker image to: *demisto/fastapi:1.0.0.86524*. diff --git a/Packs/GitHub/pack_metadata.json b/Packs/GitHub/pack_metadata.json index 4429f9c58998..e207af58630f 100644 --- a/Packs/GitHub/pack_metadata.json +++ b/Packs/GitHub/pack_metadata.json @@ -2,7 +2,7 @@ "name": "GitHub", "description": "Manage GitHub issues and pull requests directly from Cortex XSOAR", "support": "xsoar", - "currentVersion": "2.0.27", + "currentVersion": "2.0.28", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From ab43da0f8a9e235835e1946b690a16894bcf63dd Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:43:38 +0200 Subject: [PATCH 047/272] Update `demisto/etl2pcap` 25-40 coverage rate (#32674) * upgrade images * update RN --- Packs/WindowsForensics/ReleaseNotes/1_0_5.md | 6 ++++++ Packs/WindowsForensics/Scripts/Etl2Pcap/Etl2Pcap.yml | 2 +- Packs/WindowsForensics/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/WindowsForensics/ReleaseNotes/1_0_5.md diff --git a/Packs/WindowsForensics/ReleaseNotes/1_0_5.md b/Packs/WindowsForensics/ReleaseNotes/1_0_5.md new file mode 100644 index 000000000000..7f4e7db2b42d --- /dev/null +++ b/Packs/WindowsForensics/ReleaseNotes/1_0_5.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### Etl2Pcap + +- Updated the Docker image to: *demisto/etl2pcap:1.0.0.86370*. diff --git a/Packs/WindowsForensics/Scripts/Etl2Pcap/Etl2Pcap.yml b/Packs/WindowsForensics/Scripts/Etl2Pcap/Etl2Pcap.yml index 222a87d16052..d7b65c504b08 100644 --- a/Packs/WindowsForensics/Scripts/Etl2Pcap/Etl2Pcap.yml +++ b/Packs/WindowsForensics/Scripts/Etl2Pcap/Etl2Pcap.yml @@ -6,7 +6,7 @@ args: commonfields: id: Etl2Pcap version: -1 -dockerimage: demisto/etl2pcap:1.0.0.19032 +dockerimage: demisto/etl2pcap:1.0.0.86370 enabled: true name: Etl2Pcap outputs: diff --git a/Packs/WindowsForensics/pack_metadata.json b/Packs/WindowsForensics/pack_metadata.json index ddf6c0842b05..8fbbab8c3182 100644 --- a/Packs/WindowsForensics/pack_metadata.json +++ b/Packs/WindowsForensics/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Windows Forensics", "description": "Acquires forensic data from Windows hosts by leveraging Windows built-in capabilities.", "support": "xsoar", - "currentVersion": "1.0.4", + "currentVersion": "1.0.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 076e0c9ec700140c284da33cb220f5d2e4f30a48 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:48:10 +0200 Subject: [PATCH 048/272] Update `demisto/btfl-soup` 25-40 coverage rate (#32627) * upgrade images * update RN --- .../AzureADConnectHealthFeed/AzureADConnectHealthFeed.yml | 2 +- Packs/FeedAzureADConnectHealth/ReleaseNotes/1_0_20.md | 6 ++++++ Packs/FeedAzureADConnectHealth/pack_metadata.json | 2 +- Packs/FeedZoom/Integrations/FeedZoom/FeedZoom.yml | 2 +- Packs/FeedZoom/ReleaseNotes/1_1_14.md | 6 ++++++ Packs/FeedZoom/pack_metadata.json | 2 +- 6 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 Packs/FeedAzureADConnectHealth/ReleaseNotes/1_0_20.md create mode 100644 Packs/FeedZoom/ReleaseNotes/1_1_14.md diff --git a/Packs/FeedAzureADConnectHealth/Integrations/AzureADConnectHealthFeed/AzureADConnectHealthFeed.yml b/Packs/FeedAzureADConnectHealth/Integrations/AzureADConnectHealthFeed/AzureADConnectHealthFeed.yml index 741f1852ee37..b3382a253ef7 100644 --- a/Packs/FeedAzureADConnectHealth/Integrations/AzureADConnectHealthFeed/AzureADConnectHealthFeed.yml +++ b/Packs/FeedAzureADConnectHealth/Integrations/AzureADConnectHealthFeed/AzureADConnectHealthFeed.yml @@ -101,6 +101,6 @@ script: description: The maximum number of results to return. The default value is 10. defaultValue: "0" description: Gets indicators from the feed. - dockerimage: demisto/btfl-soup:1.0.1.45563 + dockerimage: demisto/btfl-soup:1.0.1.86352 feed: true subtype: python3 diff --git a/Packs/FeedAzureADConnectHealth/ReleaseNotes/1_0_20.md b/Packs/FeedAzureADConnectHealth/ReleaseNotes/1_0_20.md new file mode 100644 index 000000000000..45d09082bbfa --- /dev/null +++ b/Packs/FeedAzureADConnectHealth/ReleaseNotes/1_0_20.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure AD Connect Health Feed + +- Updated the Docker image to: *demisto/btfl-soup:1.0.1.86352*. diff --git a/Packs/FeedAzureADConnectHealth/pack_metadata.json b/Packs/FeedAzureADConnectHealth/pack_metadata.json index 426948658f3f..f05e861a3857 100644 --- a/Packs/FeedAzureADConnectHealth/pack_metadata.json +++ b/Packs/FeedAzureADConnectHealth/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Azure AD Connect Health Feed", "description": "Indicator feed from Microsoft Azure AD Connect Health endpoints, fetching URLs and DomainGlobs used by Azure AD, with which you can create a list (allowlist, EDL, etc.) for your SIEM or firewall service to ingest and apply to its policy rules.", "support": "xsoar", - "currentVersion": "1.0.19", + "currentVersion": "1.0.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FeedZoom/Integrations/FeedZoom/FeedZoom.yml b/Packs/FeedZoom/Integrations/FeedZoom/FeedZoom.yml index 70847d605621..83d84847b6bf 100644 --- a/Packs/FeedZoom/Integrations/FeedZoom/FeedZoom.yml +++ b/Packs/FeedZoom/Integrations/FeedZoom/FeedZoom.yml @@ -122,7 +122,7 @@ script: description: The maximum number of results to return. The default value is 10. defaultValue: "10" description: Gets indicators from the feed. - dockerimage: demisto/btfl-soup:1.0.1.45563 + dockerimage: demisto/btfl-soup:1.0.1.86352 feed: true subtype: python3 tests: diff --git a/Packs/FeedZoom/ReleaseNotes/1_1_14.md b/Packs/FeedZoom/ReleaseNotes/1_1_14.md new file mode 100644 index 000000000000..a160cae173c7 --- /dev/null +++ b/Packs/FeedZoom/ReleaseNotes/1_1_14.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Zoom Feed + +- Updated the Docker image to: *demisto/btfl-soup:1.0.1.86352*. diff --git a/Packs/FeedZoom/pack_metadata.json b/Packs/FeedZoom/pack_metadata.json index 7018029975f7..ff6abcc95394 100644 --- a/Packs/FeedZoom/pack_metadata.json +++ b/Packs/FeedZoom/pack_metadata.json @@ -5,7 +5,7 @@ "videos": [ "https://www.youtube.com/embed/s9lRtJltTGI" ], - "currentVersion": "1.1.13", + "currentVersion": "1.1.14", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From a6e7972d7b5c47bc0d041c3c19bdf44a0c2499b0 Mon Sep 17 00:00:00 2001 From: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:34:42 +0200 Subject: [PATCH 049/272] [Microsoft Graph Security] Update msg-update-alert documentation (#32983) * update docs * update dockers * add "MSG-ediscovery-tpb" to skipped_tests --- .../MicrosoftGraphSecurity.yml | 6 ++--- .../MicrosoftGraphSecurity/README.md | 26 +++++++++---------- .../ReleaseNotes/2_2_8.md | 6 +++++ .../MicrosoftGraphSecurity/pack_metadata.json | 2 +- Tests/conf.json | 3 ++- 5 files changed, 24 insertions(+), 19 deletions(-) create mode 100644 Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_8.md diff --git a/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml b/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml index 0549545d5769..26b8e904938d 100644 --- a/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml +++ b/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml @@ -689,17 +689,15 @@ script: - unknown - truePositive - falsePositive - - benignPositive + - informationalExpectedActivity - auto: PREDEFINED description: Relevant only for Alerts v2. Use this field to update the alert's determination. name: determination predefined: - unknown - - apt - malware - phishing - other - - securityPersonnel - securityTesting - multiStagedAttack - maliciousUserActivity @@ -2038,7 +2036,7 @@ script: - contextPath: MSGraphMail.AssessmentRequest.ResultMessage description: The result message of the assessment request. type: String - dockerimage: demisto/crypto:1.0.0.82826 + dockerimage: demisto/crypto:1.0.0.87358 isfetch: true runonce: false script: '-' diff --git a/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/README.md b/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/README.md index dd810ab4fd86..575463ac0e3d 100644 --- a/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/README.md +++ b/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/README.md @@ -377,19 +377,19 @@ Update an editable alert property within any integrated solution to keep alert s #### Input -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| alert_id | The Alert ID. Provider-generated GUID/unique identifier. | Required | -| assigned_to | Name of the analyst the alert is assigned to for triage, investigation, or remediation. | Optional | -| closed_date_time | Relevant only for Legacy Alerts. Time the alert was closed in the string format MM/DD/YYYY. | Optional | -| comments | Relevant only for Legacy Alerts. Analyst comments on the alert (for customer alert management). | Optional | -| feedback | Relevant only for Legacy Alerts. Analyst feedback on the alert. Possible values are: unknown, truePositive, falsePositive, benignPositive. | Optional | -| status | Alert lifecycle status (stage). Possible values are: unknown, newAlert, inProgress, resolved, new. | Optional | -| tags | Relevant only for Legacy Alerts. User-definable labels that can be applied to an alert and can serve as filter conditions, for example "HVA", "SAW). | Optional | -| vendor_information | Relevant only for Legacy Alerts. Details about the security service vendor, for example Microsoft. | Optional | -| provider_information | Relevant only for Legacy Alerts. Details about the security service vendor, for example Windows Defender ATP. | Optional | -| classification | Relevant only for Alerts v2. Use this field to update the alert's classification. Possible values are: unknown, truePositive, falsePositive, benignPositive. | Optional | -| determination | Relevant only for Alerts v2. Use this field to update the alert's determination. Possible values are: unknown, apt, malware, phishing, other, securityPersonnel, securityTesting, multiStagedAttack, maliciousUserActivity, lineOfBusinessApplication, unwantedSoftware. | Optional | +| **Argument Name** | **Description** | **Required** | +|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------| +| alert_id | The Alert ID. Provider-generated GUID/unique identifier. | Required | +| assigned_to | Name of the analyst the alert is assigned to for triage, investigation, or remediation. | Optional | +| closed_date_time | Relevant only for Legacy Alerts. Time the alert was closed in the string format MM/DD/YYYY. | Optional | +| comments | Relevant only for Legacy Alerts. Analyst comments on the alert (for customer alert management). | Optional | +| feedback | Relevant only for Legacy Alerts. Analyst feedback on the alert. Possible values are: unknown, truePositive, falsePositive, benignPositive. | Optional | +| status | Alert lifecycle status (stage). Possible values are: unknown, newAlert, inProgress, resolved, new. | Optional | +| tags | Relevant only for Legacy Alerts. User-definable labels that can be applied to an alert and can serve as filter conditions, for example "HVA", "SAW). | Optional | +| vendor_information | Relevant only for Legacy Alerts. Details about the security service vendor, for example Microsoft. | Optional | +| provider_information | Relevant only for Legacy Alerts. Details about the security service vendor, for example Windows Defender ATP. | Optional | +| classification | Relevant only for Alerts v2. Use this field to update the alert's classification. Possible values are: unknown, truePositive, falsePositive, informationalExpectedActivity. | Optional | +| determination | Relevant only for Alerts v2. Use this field to update the alert's determination. Possible values are: unknown, malware, phishing, other, securityTesting, multiStagedAttack, maliciousUserActivity, lineOfBusinessApplication, unwantedSoftware. | Optional | #### Context Output diff --git a/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_8.md b/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_8.md new file mode 100644 index 000000000000..173bed488262 --- /dev/null +++ b/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_8.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Graph Security +- Updated the documentation for the ***msg-update-alert*** command to include only the determination and classification options supported by Microsoft. +- Updated the Docker image to: *demisto/crypto:1.0.0.87358*. \ No newline at end of file diff --git a/Packs/MicrosoftGraphSecurity/pack_metadata.json b/Packs/MicrosoftGraphSecurity/pack_metadata.json index 32e829feb988..0cefa88a578c 100644 --- a/Packs/MicrosoftGraphSecurity/pack_metadata.json +++ b/Packs/MicrosoftGraphSecurity/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Security", "description": "Unified gateway to security insights - all from a unified Microsoft Graph\n Security API.", "support": "xsoar", - "currentVersion": "2.2.7", + "currentVersion": "2.2.8", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Tests/conf.json b/Tests/conf.json index fdc83215ea3d..0cfb66b0a6c3 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -5865,7 +5865,8 @@ "ThreatStream-Test": "Issue CRTX-96526", "MSG-Threat-Assessment-test": "API limitation", "BambenekConsultingFeed_Test": "Issue CRTX-99480", - "AWS SNS Listener - Test": "Cant validate mock msg against AWS-SNS in TBP" + "AWS SNS Listener - Test": "Cant validate mock msg against AWS-SNS in TBP", + "MSG-ediscovery-tpb": "Issue CIAC-9763" }, "skipped_integrations": { "EWS Mail Sender": "The integration is deprecated", From f3b883c5df1c823f97629cebd6cff3432b4975a8 Mon Sep 17 00:00:00 2001 From: Moshe Eichler <78307768+MosheEichler@users.noreply.github.com> Date: Tue, 20 Feb 2024 13:13:44 +0200 Subject: [PATCH 050/272] Ignore E2E jobs in check jobs are really done (#32963) --- Tests/scripts/check_jobs_done.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/scripts/check_jobs_done.py b/Tests/scripts/check_jobs_done.py index 85047318ee47..2138ccbbe6a3 100644 --- a/Tests/scripts/check_jobs_done.py +++ b/Tests/scripts/check_jobs_done.py @@ -15,7 +15,7 @@ 'xpanse-prepare-testing-bucket', 'xsoar-prepare-testing-bucket', 'xsiam_server_ga', - 'xsoar_ng_server_ga', + # 'xsoar_ng_server_ga', 'tests_xsoar_server: [Server 6.9]', 'tests_xsoar_server: [Server 6.10]', 'tests_xsoar_server: [Server 6.11]', @@ -25,7 +25,7 @@ 'xsiam-test_playbooks_results', 'xsiam-test_modeling_rule_results', 'cloning-content-repo-last-upload-commit', - 'xsoar-saas_test_e2e_results', + # 'xsoar-saas_test_e2e_results', ] SDK_NIGHTLY_JOBS = [ From 151317ce37c59ca044a8ec5f2f66095301e09922 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 13:32:31 +0200 Subject: [PATCH 051/272] update docker + RN (#33000) --- .../Active_Directory_Query/Active_Directory_Query.yml | 2 +- Packs/Active_Directory_Query/ReleaseNotes/1_6_29.md | 6 ++++++ Packs/Active_Directory_Query/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/Active_Directory_Query/ReleaseNotes/1_6_29.md diff --git a/Packs/Active_Directory_Query/Integrations/Active_Directory_Query/Active_Directory_Query.yml b/Packs/Active_Directory_Query/Integrations/Active_Directory_Query/Active_Directory_Query.yml index 6ea4292169a2..92b344faf982 100644 --- a/Packs/Active_Directory_Query/Integrations/Active_Directory_Query/Active_Directory_Query.yml +++ b/Packs/Active_Directory_Query/Integrations/Active_Directory_Query/Active_Directory_Query.yml @@ -800,7 +800,7 @@ script: outputs: - contextPath: ActiveDirectory.ValidCredentials description: List of usernames that successfully logged in. - dockerimage: demisto/ldap:2.9.1.87300 + dockerimage: demisto/ldap:2.9.1.87744 ismappable: true isremotesyncout: true runonce: false diff --git a/Packs/Active_Directory_Query/ReleaseNotes/1_6_29.md b/Packs/Active_Directory_Query/ReleaseNotes/1_6_29.md new file mode 100644 index 000000000000..6083963f08a8 --- /dev/null +++ b/Packs/Active_Directory_Query/ReleaseNotes/1_6_29.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Active Directory Query v2 + +- Updated the Docker image to: *demisto/ldap:2.9.1.87744*. diff --git a/Packs/Active_Directory_Query/pack_metadata.json b/Packs/Active_Directory_Query/pack_metadata.json index 28985171074b..c5b7d124933e 100644 --- a/Packs/Active_Directory_Query/pack_metadata.json +++ b/Packs/Active_Directory_Query/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Active Directory Query", "description": "Active Directory Query integration enables you to access and manage Active Directory objects (users, contacts, and computers).", "support": "xsoar", - "currentVersion": "1.6.28", + "currentVersion": "1.6.29", "author": "Cortex XSOAR", "url": "", "email": "", From 24fbd75ea4bc5451db539487fe2bf32bcf0a2114 Mon Sep 17 00:00:00 2001 From: JudithB <132264628+jbabazadeh@users.noreply.github.com> Date: Tue, 20 Feb 2024 14:29:19 +0200 Subject: [PATCH 052/272] troubleshooting splunk cloud (#33019) * troubleshooting splunk cloud * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- Packs/SplunkPy/Integrations/SplunkPy/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Packs/SplunkPy/Integrations/SplunkPy/README.md b/Packs/SplunkPy/Integrations/SplunkPy/README.md index 611cc4ad63a9..405f5439bebb 100644 --- a/Packs/SplunkPy/Integrations/SplunkPy/README.md +++ b/Packs/SplunkPy/Integrations/SplunkPy/README.md @@ -1132,3 +1132,16 @@ The default port is 8088. ## Troubleshooting In case you encounter HTTP errors (e.g., IncompleteRead), we recommend using Python requests handler. + +If you encounter connectivity issues while using **Splunk Cloud** within Cortex XSOAR8 or Cortex XSIAM you may receive the following error: + + requests.exceptions.ConnectTimeout: + HTTPSConnectionPool(host='.splunkcloud.com', port=8089) + : Max retries exceeded with url: /services/auth/login (Caused by ConnectTimeoutError(, + 'Connection to .splunkcloud.com timed out. + (connect timeout=None)')) + +To resolve this issue, add the IP addresses of Cortex XSOAR8 or Cortex XSIAM to the Splunk Cloud whitelist. +You can find the relevant IP addresses at: +[Cortex XSOAR Administrator Guide](https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8/Cortex-XSOAR-Administrator-Guide/Enable-Access-to-Cortex-XSOAR) +under **Used for communication between Cortex XSOAR and customer resources**. Choose the IP address corresponding to your Cortex XSOAR region. \ No newline at end of file From 2abddeb516aaed6424ef5775d88c5022d39559b5 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Tue, 20 Feb 2024 14:30:31 +0200 Subject: [PATCH 053/272] AWS Cloud Watch logs - fix proxy issue (#32956) (#33024) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix proxy issue * format yml * Update Packs/AWS-CloudWatchLogs/Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml * Update Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md * format and ReleaseNotes * ReleaseNotes * add 1_2_20 --------- Co-authored-by: Fábio Dias Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> Co-authored-by: Moshe Eichler <78307768+MosheEichler@users.noreply.github.com> --- Packs/AWS-CloudWatchLogs/CONTRIBUTORS.json | 3 +++ .../AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml | 9 +++++++-- Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md | 3 ++- Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_20.md | 7 +++++++ Packs/AWS-CloudWatchLogs/pack_metadata.json | 4 ++-- 5 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 Packs/AWS-CloudWatchLogs/CONTRIBUTORS.json create mode 100644 Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_20.md diff --git a/Packs/AWS-CloudWatchLogs/CONTRIBUTORS.json b/Packs/AWS-CloudWatchLogs/CONTRIBUTORS.json new file mode 100644 index 000000000000..ce9d08a30890 --- /dev/null +++ b/Packs/AWS-CloudWatchLogs/CONTRIBUTORS.json @@ -0,0 +1,3 @@ +[ + "Fabio Dias" +] diff --git a/Packs/AWS-CloudWatchLogs/Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml b/Packs/AWS-CloudWatchLogs/Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml index 688073e08848..5d9018f63cc4 100644 --- a/Packs/AWS-CloudWatchLogs/Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml +++ b/Packs/AWS-CloudWatchLogs/Integrations/AWS-CloudWatchLogs/AWS-CloudWatchLogs.yml @@ -65,6 +65,11 @@ configuration: section: Connect advanced: true required: false +- display: Use system proxy settings + name: proxy + type: 8 + required: false + section: Connect script: script: '' type: python @@ -335,7 +340,7 @@ script: description: The name of the log stream. - name: timestamp required: true - description: The time the event occurred, expressed as the number of milliseconds fter Jan 1, 1970 00:00:00 UTC. (Unix Time) + description: The time the event occurred, expressed as the number of milliseconds fter Jan 1, 1970 00:00:00 UTC. (Unix Time). - name: message required: true description: The raw event message. @@ -447,7 +452,7 @@ script: description: The name of the log group. type: string description: Lists the specified metric filters. You can list all the metric filters or filter the results by log name, prefix, metric name, or metric namespace. - dockerimage: demisto/boto3py3:1.0.0.87655 + dockerimage: demisto/boto3py3:1.0.0.88114 tests: - No Tests fromversion: 5.0.0 diff --git a/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md b/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md index 9078c2c905c1..1a451b1b6985 100644 --- a/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md +++ b/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_19.md @@ -3,4 +3,5 @@ ##### AWS - CloudWatchLogs -- Updated the Docker image to: *demisto/boto3py3:1.0.0.87655*. +- Updated the Docker image to: demisto/boto3py3:1.0.0.87655. + diff --git a/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_20.md b/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_20.md new file mode 100644 index 000000000000..deb4c79ae5aa --- /dev/null +++ b/Packs/AWS-CloudWatchLogs/ReleaseNotes/1_2_20.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### AWS - CloudWatchLogs + +- Added the *Use system proxy settings* parameter. +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88114*. diff --git a/Packs/AWS-CloudWatchLogs/pack_metadata.json b/Packs/AWS-CloudWatchLogs/pack_metadata.json index ac7edd3c9b04..8168a7f79e79 100644 --- a/Packs/AWS-CloudWatchLogs/pack_metadata.json +++ b/Packs/AWS-CloudWatchLogs/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - CloudWatchLogs", "description": "Amazon Web Services CloudWatch Logs (logs).", "support": "xsoar", - "currentVersion": "1.2.19", + "currentVersion": "1.2.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", @@ -18,4 +18,4 @@ "marketplacev2", "xpanse" ] -} \ No newline at end of file +} From 2510e4cedbeb3f18dcf9f4cf2d63811ed45d0c46 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Tue, 20 Feb 2024 14:54:05 +0200 Subject: [PATCH 054/272] fix + RN (#32990) --- Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.py | 6 ++---- .../ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.yml | 2 +- Packs/ServiceNow/ReleaseNotes/2_5_54.md | 7 +++++++ Packs/ServiceNow/pack_metadata.json | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 Packs/ServiceNow/ReleaseNotes/2_5_54.md diff --git a/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.py b/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.py index e16f4af02853..dade0ad6689d 100644 --- a/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.py +++ b/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.py @@ -1,7 +1,6 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 import re -import shutil from collections.abc import Callable, Iterable @@ -709,8 +708,8 @@ def send_request(self, path: str, method: str = 'GET', body: dict | None = None, try: file_entry = file['id'] file_name = file['name'] - shutil.copy(demisto.getFilePath(file_entry)['path'], file_name) - with open(file_name, 'rb') as f: + file_path = demisto.getFilePath(file_entry)['path'] + with open(file_path, 'rb') as f: file_info = (file_name, f, self.get_content_type(file_name)) if self.use_oauth: access_token = self.snow_client.get_access_token() @@ -723,7 +722,6 @@ def send_request(self, path: str, method: str = 'GET', body: dict | None = None, res = requests.request(method, url, headers=headers, data=body, params=params, files={'file': file_info}, auth=self._auth, verify=self._verify, proxies=self._proxies) - shutil.rmtree(demisto.getFilePath(file_entry)['name'], ignore_errors=True) except Exception as err: raise Exception('Failed to upload file - ' + str(err)) else: diff --git a/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.yml b/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.yml index aea11526c403..203187ff0d66 100644 --- a/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.yml +++ b/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.yml @@ -1610,7 +1610,7 @@ script: - contextPath: ServiceNow.Generic.Response description: Generic response to servicenow api. type: string - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true ismappable: true isremotesyncin: true diff --git a/Packs/ServiceNow/ReleaseNotes/2_5_54.md b/Packs/ServiceNow/ReleaseNotes/2_5_54.md new file mode 100644 index 000000000000..4e3fd141b79d --- /dev/null +++ b/Packs/ServiceNow/ReleaseNotes/2_5_54.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### ServiceNow v2 + +- Fixed an issue where the ***servicenow-upload-file*** command failed in case the file name contained invalid characters. +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. \ No newline at end of file diff --git a/Packs/ServiceNow/pack_metadata.json b/Packs/ServiceNow/pack_metadata.json index 24af09c0df5f..876ef3d88ae7 100644 --- a/Packs/ServiceNow/pack_metadata.json +++ b/Packs/ServiceNow/pack_metadata.json @@ -2,7 +2,7 @@ "name": "ServiceNow", "description": "Use The ServiceNow IT Service Management (ITSM) solution to modernize the way you manage and deliver services to your users.", "support": "xsoar", - "currentVersion": "2.5.53", + "currentVersion": "2.5.54", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 6b2e5afe980bc182350ab1cae957ca0f237355b8 Mon Sep 17 00:00:00 2001 From: Moshe Eichler <78307768+MosheEichler@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:29:08 +0200 Subject: [PATCH 055/272] Add nightly ok label workflow (#32876) * Add nightly ran GitHub workflow * change label name * change label name * update message * remove continue on error * changed gitlab * update workflow * change name * typo * Update on call to Edri&Polishuk (#32964) * bug - Cortex IR resolved incidents not mirrored correctly (#32856) * bug - Cortex IR resolved incidents not mirrored correctly * Possible fix * RN * Bump pack from version CortexXDR to 6.1.16. * pre commit * rn * pre-commit * fix test * pre commit --------- Co-authored-by: Content Bot * Update Docker Image To demisto/taxii-server (#32897) * Updated Metadata Of Pack CybleThreatIntel * Added release notes to pack CybleThreatIntel * Packs/CybleThreatIntel/Integrations/CybleThreatIntel/CybleThreatIntel.yml Docker image update * EXPANDR-8026: Azure Remediation Bug Fix and Improvements (#32882) (#32941) * update files * RN * RN part 2 * Apply suggestions from code review --------- Co-authored-by: johnnywilkes <32227961+johnnywilkes@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> Co-authored-by: Yuval Cohen <86777474+yucohen@users.noreply.github.com> * change to run * cr fixes * fix git diff * add git checkout * origin * github event * chckout * master * GITHUB_REF * change name * only master * fetch origin master * remove print * chekcout * 0 * fi * add origin * fix syntax * revert gitlab * add if * change else * curl brackets * remove n * $GITHUB_OUTPUT * gitlab change * print * revert * add changed files null * commit * echo * comment * without grep * fix * new line * gitlab changed * remove ^ * remove " * gitlab/ci * use * * GITLAB_CHANGED_FILES * fix check * console log outputs * fix logs * add $ * remove logs * remove true * revert * log * impement if * add brackets * gitlab * revert gitlab --------- Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> Co-authored-by: Content Bot Co-authored-by: content-bot <55035720+content-bot@users.noreply.github.com> Co-authored-by: johnnywilkes <32227961+johnnywilkes@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> Co-authored-by: Yuval Cohen <86777474+yucohen@users.noreply.github.com> --- .github/workflows/ckeck-nightly-ok-label.yml | 50 ++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/ckeck-nightly-ok-label.yml diff --git a/.github/workflows/ckeck-nightly-ok-label.yml b/.github/workflows/ckeck-nightly-ok-label.yml new file mode 100644 index 000000000000..70959ad08eac --- /dev/null +++ b/.github/workflows/ckeck-nightly-ok-label.yml @@ -0,0 +1,50 @@ +name: Check nightly-ok label + +on: + pull_request: + types: [opened, synchronize, labeled, unlabeled] + +jobs: + check_label: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Check if files under .gitlab directory are changed + id: check-changes + run: | + CHANGED_FILES=$(git diff --name-only origin/master origin/${{ github.head_ref || github.ref_name }}) + echo "All changed files:" + echo "${CHANGED_FILES}" + GITLAB_CHANGED_FILES=$( [[ $CHANGED_FILES == *".gitlab/ci"* ]] && echo true || echo false) + echo "Files in the.gitlab folder have changed: ${GITLAB_CHANGED_FILES}" + echo "gitlab_changed_files=$GITLAB_CHANGED_FILES" >> $GITHUB_OUTPUT + if [[ $GITLAB_CHANGED_FILES == true ]]; then + echo 'Files under .gitlab folder has changed, Will check if the PR has the `nightly-ok` label.' + else + echo 'Files in the.gitlab folder have not been changed.' + fi + + - name: Check if PR has the nightly-ok label + uses: actions/github-script@v7 + id: check-label + with: + script: | + const gitlabChangedFiles = ${{ steps.check-changes.outputs.gitlab_changed_files }}; + if(gitlabChangedFiles) { + console.log('Files under .gitlab folder has changed, Will check if the PR has the `nightly-ok` label.'); + const labels = context.payload.pull_request.labels.map(label => label.name); + const hasLabel = labels.includes('nightly-ok'); + if (hasLabel) { + console.log('All good, the PR has the `nightly-ok` label.'); + } else { + console.log('PR does not have the `nightly-ok` label. It is required when changing files under the `.gitlab` directory. Please run nightly using the Utils/gitlab_triggers/trigger_content_nightly_build.sh script, check that succeeded, and add the `nightly-ok` label'); + process.exit(1); // Exit with failure status if label is missing + } + } else { + console.log('Files in the.gitlab folder have not been changed.'); + } From 2d351cec065344c955940c57aa40db026a77bfc8 Mon Sep 17 00:00:00 2001 From: ilaner <88267954+ilaner@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:18:44 +0200 Subject: [PATCH 056/272] [FeedElasticSearch] Fix ids in last run (#32778) --- .../FeedElasticsearch/FeedElasticsearch.py | 35 +++++++++++++------ .../FeedElasticsearch_test.py | 2 +- Packs/FeedElasticsearch/ReleaseNotes/1_1_5.md | 6 ++++ Packs/FeedElasticsearch/pack_metadata.json | 2 +- 4 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 Packs/FeedElasticsearch/ReleaseNotes/1_1_5.md diff --git a/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch.py b/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch.py index b217bd9e652e..ce7edf37783e 100644 --- a/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch.py +++ b/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch.py @@ -210,23 +210,33 @@ def get_demisto_indicators(search, tags, tlp_color): def update_last_fetch(client, ioc_lst): - last_calculated_time = None + demisto.debug(f"ElasticSearchFeed: Length of the indicators to fetch is: {len(ioc_lst)}") + last_calculated_timestamp = None last_ids = [] for ioc in reversed(ioc_lst): calculate_time = dateparser.parse(ioc.get(client.time_field)) - if calculate_time and (not last_calculated_time or calculate_time >= last_calculated_time): - last_calculated_time = calculate_time + if not calculate_time: + demisto.info(f"ioc {ioc.get('name')} if missing {client.time_field}") + break + calculate_timestamp = int(calculate_time.timestamp() * 1000) + if not last_calculated_timestamp or calculate_timestamp >= last_calculated_timestamp: + last_calculated_timestamp = calculate_timestamp last_ids.append(ioc.get('id')) else: + demisto.debug(f"FeedElasticSearch: {last_calculated_timestamp=}") + demisto.debug(f"FeedElasticSearch: {calculate_timestamp=}") break - if last_calculated_time is None: - last_calculated_time = datetime.now() - return last_calculated_time, last_ids + if last_calculated_timestamp is None: + last_calculated_timestamp = int(datetime.now().timestamp() * 1000) + demisto.info(f"FeedElasticSearch: The length of the indicators of the last time: {len(last_ids)}") + demisto.debug(f"FeedElasticSearch: The last ids which were fetched with the same last time: {last_ids}") + return last_calculated_timestamp, last_ids def fetch_indicators_command(client, feed_type, src_val, src_type, default_type, last_fetch, fetch_limit): """Implements fetch-indicators command""" last_fetch_timestamp = get_last_fetch_timestamp(last_fetch, client.time_method, client.fetch_time) + demisto.debug(f"FeedElasticSearch: last_fetch_timestamp is: {last_fetch_timestamp}") prev_iocs_ids = demisto.getLastRun().get("ids", []) now = datetime.now() ioc_lst: list = [] @@ -248,14 +258,16 @@ def fetch_indicators_command(client, feed_type, src_val, src_type, default_type, if ioc_lst: for b in batch(ioc_lst, batch_size=2000): demisto.createIndicators(b) - last_calculated_time, last_ids = update_last_fetch(client, ioc_lst) + last_calculated_timestamp, last_ids = update_last_fetch(client, ioc_lst) + if str(last_calculated_timestamp) == last_fetch: + last_ids.extend(prev_iocs_ids) if ioc_enrch_lst: ioc_enrch_batches = create_enrichment_batches(ioc_enrch_lst) for enrch_batch in ioc_enrch_batches: # ensure batch sizes don't exceed 2000 for b in batch(enrch_batch, batch_size=2000): demisto.createIndicators(b) - demisto.setLastRun({'time': int(last_calculated_time.timestamp() * 1000), 'ids': last_ids}) + demisto.setLastRun({'time': str(last_calculated_timestamp), 'ids': last_ids}) def get_last_fetch_timestamp(last_fetch, time_method, fetch_time): @@ -263,7 +275,9 @@ def get_last_fetch_timestamp(last_fetch, time_method, fetch_time): if last_fetch: last_fetch_timestamp = last_fetch else: - last_fetch, _ = parse_date_range(date_range=fetch_time, utc=False) + last_fetch = dateparser.parse(fetch_time) + if not last_fetch: + raise ValueError("Failed to parse the fetch time") # if timestamp: get the last fetch to the correct format of timestamp last_fetch_timestamp = int(last_fetch.timestamp() * 1000) if 'Timestamp - Seconds' in time_method: @@ -284,7 +298,8 @@ def get_scan_generic_format(client, now, last_fetch_timestamp=None, fetch_limit= range_field = { time_field: {'gte': last_fetch_timestamp, 'lte': now}} if last_fetch_timestamp else { time_field: {'lte': now}} - search = Search(using=es, index=fetch_index).filter({'range': range_field}).extra(size=fetch_limit).sort().query(query) + search = Search(using=es, index=fetch_index).filter({'range': range_field}).extra( + size=fetch_limit).sort({time_field: {'order': 'asc'}}).query(query) else: search = Search(using=es, index=fetch_index).query(QueryString(query=client.query)) return search diff --git a/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch_test.py b/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch_test.py index 88b4b494de4c..f5f4f05f644f 100644 --- a/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch_test.py +++ b/Packs/FeedElasticsearch/Integrations/FeedElasticsearch/FeedElasticsearch_test.py @@ -307,4 +307,4 @@ def test_last_run(): {"id": "4", "calculatedTime": "2023-01-17T14:33:00.000Z"}] last_update, last_ids = update_last_fetch(MockClient(), ioc_lst) assert set(last_ids) == {"4", "3"} - assert last_update.isoformat() == "2023-01-17T14:33:00+00:00" + assert datetime.fromtimestamp(last_update // 1000).isoformat() == "2023-01-17T14:33:00" diff --git a/Packs/FeedElasticsearch/ReleaseNotes/1_1_5.md b/Packs/FeedElasticsearch/ReleaseNotes/1_1_5.md new file mode 100644 index 000000000000..99155146fc6f --- /dev/null +++ b/Packs/FeedElasticsearch/ReleaseNotes/1_1_5.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Elasticsearch Feed + +- Fixed an issue where the `fetch-indicators` time calculation was inaccurate. diff --git a/Packs/FeedElasticsearch/pack_metadata.json b/Packs/FeedElasticsearch/pack_metadata.json index 120f74204d14..0c6bfa76440f 100644 --- a/Packs/FeedElasticsearch/pack_metadata.json +++ b/Packs/FeedElasticsearch/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Elasticsearch Feed", "description": "Indicators feed from Elasticsearch database", "support": "xsoar", - "currentVersion": "1.1.4", + "currentVersion": "1.1.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From b1329c7404c5639d2d6aabd13688f912f1393173 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Wed, 21 Feb 2024 08:59:31 +0200 Subject: [PATCH 057/272] Update Docker Image To demisto/crypto (#33042) * Updated Metadata Of Pack MicrosoftTeams * Added release notes to pack MicrosoftTeams * Packs/MicrosoftTeams/Integrations/MicrosoftTeamsManagement/MicrosoftTeamsManagement.yml Docker image update --- .../MicrosoftTeamsManagement/MicrosoftTeamsManagement.yml | 2 +- Packs/MicrosoftTeams/ReleaseNotes/1_4_51.md | 3 +++ Packs/MicrosoftTeams/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/MicrosoftTeams/ReleaseNotes/1_4_51.md diff --git a/Packs/MicrosoftTeams/Integrations/MicrosoftTeamsManagement/MicrosoftTeamsManagement.yml b/Packs/MicrosoftTeams/Integrations/MicrosoftTeamsManagement/MicrosoftTeamsManagement.yml index 8aa876359f85..86cbd5b5ce27 100644 --- a/Packs/MicrosoftTeams/Integrations/MicrosoftTeamsManagement/MicrosoftTeamsManagement.yml +++ b/Packs/MicrosoftTeams/Integrations/MicrosoftTeamsManagement/MicrosoftTeamsManagement.yml @@ -679,7 +679,7 @@ script: - contextPath: MicrosoftTeams.Team.description description: An optional description for the group. type: String - dockerimage: demisto/crypto:1.0.0.83343 + dockerimage: demisto/crypto:1.0.0.87358 runonce: false script: '-' subtype: python3 diff --git a/Packs/MicrosoftTeams/ReleaseNotes/1_4_51.md b/Packs/MicrosoftTeams/ReleaseNotes/1_4_51.md new file mode 100644 index 000000000000..f71b8dfc6313 --- /dev/null +++ b/Packs/MicrosoftTeams/ReleaseNotes/1_4_51.md @@ -0,0 +1,3 @@ +#### Integrations +##### Microsoft Teams Management +- Updated the Docker image to: *demisto/crypto:1.0.0.87358*. diff --git a/Packs/MicrosoftTeams/pack_metadata.json b/Packs/MicrosoftTeams/pack_metadata.json index f33c6c004c7d..440c13ba4b05 100644 --- a/Packs/MicrosoftTeams/pack_metadata.json +++ b/Packs/MicrosoftTeams/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Teams", "description": "Send messages and notifications to your team members.", "support": "xsoar", - "currentVersion": "1.4.50", + "currentVersion": "1.4.51", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 0b9e16427221dfdc54dbfa271a94356c9a5449ef Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:02:18 +0200 Subject: [PATCH 058/272] Update Docker Image To demisto/python3 (#33040) * Updated Metadata Of Pack Darktrace * Added release notes to pack Darktrace * Packs/Darktrace/Integrations/DarktraceAdmin/DarktraceAdmin.yml Docker image update * Packs/Darktrace/Integrations/DarktraceMBs/DarktraceMBs.yml Docker image update * Packs/Darktrace/Integrations/DarktraceAIA/DarktraceAIA.yml Docker image update * Updated Metadata Of Pack ForescoutEyeInspect * Added release notes to pack ForescoutEyeInspect * Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.yml Docker image update * Updated Metadata Of Pack Stairwell * Added release notes to pack Stairwell * Packs/Stairwell/Integrations/Inception/Inception.yml Docker image update * Updated Metadata Of Pack SecureWorks * Added release notes to pack SecureWorks * Packs/SecureWorks/Integrations/TaegisXDRv2/TaegisXDRv2.yml Docker image update * Updated Metadata Of Pack BmcITSM * Added release notes to pack BmcITSM * Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml Docker image update * Updated Metadata Of Pack Tessian * Added release notes to pack Tessian * Packs/Tessian/Integrations/Tessian/Tessian.yml Docker image update * Updated Metadata Of Pack Cisco-umbrella-cloud-security * Added release notes to pack Cisco-umbrella-cloud-security * Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.yml Docker image update * Updated Metadata Of Pack SingleConnect * Added release notes to pack SingleConnect * Packs/SingleConnect/Integrations/SingleConnect/SingleConnect.yml Docker image update --- Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml | 2 +- Packs/BmcITSM/ReleaseNotes/1_0_21.md | 3 +++ Packs/BmcITSM/pack_metadata.json | 2 +- .../CiscoUmbrellaCloudSecurityv2.yml | 2 +- Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_0_8.md | 3 +++ Packs/Cisco-umbrella-cloud-security/pack_metadata.json | 2 +- Packs/Darktrace/Integrations/DarktraceAIA/DarktraceAIA.yml | 2 +- .../Integrations/DarktraceAdmin/DarktraceAdmin.yml | 2 +- Packs/Darktrace/Integrations/DarktraceMBs/DarktraceMBs.yml | 2 +- Packs/Darktrace/ReleaseNotes/3_0_10.md | 7 +++++++ Packs/Darktrace/pack_metadata.json | 2 +- .../ForescoutEyeInspect/ForescoutEyeInspect.yml | 2 +- Packs/ForescoutEyeInspect/ReleaseNotes/1_0_21.md | 3 +++ Packs/ForescoutEyeInspect/pack_metadata.json | 2 +- Packs/SecureWorks/Integrations/TaegisXDRv2/TaegisXDRv2.yml | 2 +- Packs/SecureWorks/ReleaseNotes/5_0_8.md | 3 +++ Packs/SecureWorks/pack_metadata.json | 2 +- .../Integrations/SingleConnect/SingleConnect.yml | 2 +- Packs/SingleConnect/ReleaseNotes/1_0_15.md | 3 +++ Packs/SingleConnect/pack_metadata.json | 2 +- Packs/Stairwell/Integrations/Inception/Inception.yml | 2 +- Packs/Stairwell/ReleaseNotes/1_0_16.md | 3 +++ Packs/Stairwell/pack_metadata.json | 2 +- Packs/Tessian/Integrations/Tessian/Tessian.yml | 2 +- Packs/Tessian/ReleaseNotes/1_0_4.md | 3 +++ Packs/Tessian/pack_metadata.json | 2 +- 26 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 Packs/BmcITSM/ReleaseNotes/1_0_21.md create mode 100644 Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_0_8.md create mode 100644 Packs/Darktrace/ReleaseNotes/3_0_10.md create mode 100644 Packs/ForescoutEyeInspect/ReleaseNotes/1_0_21.md create mode 100644 Packs/SecureWorks/ReleaseNotes/5_0_8.md create mode 100644 Packs/SingleConnect/ReleaseNotes/1_0_15.md create mode 100644 Packs/Stairwell/ReleaseNotes/1_0_16.md create mode 100644 Packs/Tessian/ReleaseNotes/1_0_4.md diff --git a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml index 960566803b57..c6677cdfae79 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml +++ b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml @@ -168,7 +168,7 @@ script: script: "" type: python subtype: python3 - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 commands: - name: bmc-itsm-user-list description: Retrieves a list of user profiles from BMC Helix ITSM. The records are retrieved by the query argument or by the filtering arguments. When using filtering arguments, each one defines a 'LIKE' operation and an 'AND' operator is used between them. To see the entire JSON then you can use the raw_response=true at the end of the command. diff --git a/Packs/BmcITSM/ReleaseNotes/1_0_21.md b/Packs/BmcITSM/ReleaseNotes/1_0_21.md new file mode 100644 index 000000000000..cdbe3660a348 --- /dev/null +++ b/Packs/BmcITSM/ReleaseNotes/1_0_21.md @@ -0,0 +1,3 @@ +#### Integrations +##### BMC Helix ITSM +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/BmcITSM/pack_metadata.json b/Packs/BmcITSM/pack_metadata.json index 8d096e7c5795..db114ce4f13c 100644 --- a/Packs/BmcITSM/pack_metadata.json +++ b/Packs/BmcITSM/pack_metadata.json @@ -2,7 +2,7 @@ "name": "BMC Helix ITSM", "description": "BMC Helix ITSM allows customers to manage service request, incident, change request, task, problem investigation and known error tickets.", "support": "xsoar", - "currentVersion": "1.0.20", + "currentVersion": "1.0.21", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.yml b/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.yml index f3b7588ab93e..77601f3559c7 100644 --- a/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.yml +++ b/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.yml @@ -483,7 +483,7 @@ script: script: '' type: python subtype: python3 - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetch: false fromversion: 6.9.0 tests: diff --git a/Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_0_8.md b/Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_0_8.md new file mode 100644 index 000000000000..bebf1a6fb2fd --- /dev/null +++ b/Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_0_8.md @@ -0,0 +1,3 @@ +#### Integrations +##### Cisco Umbrella Cloud Security v2 +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/Cisco-umbrella-cloud-security/pack_metadata.json b/Packs/Cisco-umbrella-cloud-security/pack_metadata.json index 353597663e1f..26375fc39992 100644 --- a/Packs/Cisco-umbrella-cloud-security/pack_metadata.json +++ b/Packs/Cisco-umbrella-cloud-security/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cisco Umbrella cloud security", "description": "Basic integration with Cisco Umbrella that allows you to add domains to destination lists (e.g. global block / allow)", "support": "xsoar", - "currentVersion": "2.0.7", + "currentVersion": "2.0.8", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Darktrace/Integrations/DarktraceAIA/DarktraceAIA.yml b/Packs/Darktrace/Integrations/DarktraceAIA/DarktraceAIA.yml index d74f5c3f6e00..22c63300f7ba 100644 --- a/Packs/Darktrace/Integrations/DarktraceAIA/DarktraceAIA.yml +++ b/Packs/Darktrace/Integrations/DarktraceAIA/DarktraceAIA.yml @@ -205,7 +205,7 @@ script: - contextPath: Darktrace.AIAnalyst.groupCategory description: Group category. type: String - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true runonce: false script: '-' diff --git a/Packs/Darktrace/Integrations/DarktraceAdmin/DarktraceAdmin.yml b/Packs/Darktrace/Integrations/DarktraceAdmin/DarktraceAdmin.yml index ffc7e4515582..cbd53562446d 100644 --- a/Packs/Darktrace/Integrations/DarktraceAdmin/DarktraceAdmin.yml +++ b/Packs/Darktrace/Integrations/DarktraceAdmin/DarktraceAdmin.yml @@ -263,7 +263,7 @@ script: - contextPath: Darktrace.Device.response description: POST action message response. type: String - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 runonce: false script: '-' subtype: python3 diff --git a/Packs/Darktrace/Integrations/DarktraceMBs/DarktraceMBs.yml b/Packs/Darktrace/Integrations/DarktraceMBs/DarktraceMBs.yml index d50eb00c82b0..0c4fadb679fa 100644 --- a/Packs/Darktrace/Integrations/DarktraceMBs/DarktraceMBs.yml +++ b/Packs/Darktrace/Integrations/DarktraceMBs/DarktraceMBs.yml @@ -238,7 +238,7 @@ script: - contextPath: Darktrace.Model.Component description: A dictionary of the details of the model. Each model might have different keys. It is recommended to run the command once to check the relevant outputs in context. type: Unknown - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true runonce: false script: '-' diff --git a/Packs/Darktrace/ReleaseNotes/3_0_10.md b/Packs/Darktrace/ReleaseNotes/3_0_10.md new file mode 100644 index 000000000000..500c440301a8 --- /dev/null +++ b/Packs/Darktrace/ReleaseNotes/3_0_10.md @@ -0,0 +1,7 @@ +#### Integrations +##### Darktrace Admin +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. +##### Darktrace Model Breaches +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. +##### Darktrace AI Analyst +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/Darktrace/pack_metadata.json b/Packs/Darktrace/pack_metadata.json index 0c141a2b0095..0635f12a65c2 100644 --- a/Packs/Darktrace/pack_metadata.json +++ b/Packs/Darktrace/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Darktrace", "description": "Populates Darktrace Model Breaches and AI Analyst Events in Cortex XSOAR, allowing for cross-platform automated investigation and response.", "support": "partner", - "currentVersion": "3.0.9", + "currentVersion": "3.0.10", "fromVersion": "5.0.0", "author": "Darktrace", "githubUser": "", diff --git a/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.yml b/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.yml index 10487bffaceb..04ce7065411e 100644 --- a/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.yml +++ b/Packs/ForescoutEyeInspect/Integrations/ForescoutEyeInspect/ForescoutEyeInspect.yml @@ -1113,7 +1113,7 @@ script: - contextPath: ForescoutEyeInspect.HostChangeLog.host_mac_addresses description: The MAC addresses associated to the host. type: String - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true runonce: false script: "-" diff --git a/Packs/ForescoutEyeInspect/ReleaseNotes/1_0_21.md b/Packs/ForescoutEyeInspect/ReleaseNotes/1_0_21.md new file mode 100644 index 000000000000..87794da30223 --- /dev/null +++ b/Packs/ForescoutEyeInspect/ReleaseNotes/1_0_21.md @@ -0,0 +1,3 @@ +#### Integrations +##### Forescout EyeInspect +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/ForescoutEyeInspect/pack_metadata.json b/Packs/ForescoutEyeInspect/pack_metadata.json index 899cb4c29805..550b2fa3c6bb 100644 --- a/Packs/ForescoutEyeInspect/pack_metadata.json +++ b/Packs/ForescoutEyeInspect/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Forescout EyeInspect", "description": "Get in-depth device visibility for OT networks", "support": "xsoar", - "currentVersion": "1.0.20", + "currentVersion": "1.0.21", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/SecureWorks/Integrations/TaegisXDRv2/TaegisXDRv2.yml b/Packs/SecureWorks/Integrations/TaegisXDRv2/TaegisXDRv2.yml index f084765aa6db..b6be3280a953 100644 --- a/Packs/SecureWorks/Integrations/TaegisXDRv2/TaegisXDRv2.yml +++ b/Packs/SecureWorks/Integrations/TaegisXDRv2/TaegisXDRv2.yml @@ -547,7 +547,7 @@ script: - contextPath: TaegisXDR.InvestigationEvidenceUpdate description: The investigation that received the update. description: Add alerts and events to an existing investigation. - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true runonce: false subtype: python3 diff --git a/Packs/SecureWorks/ReleaseNotes/5_0_8.md b/Packs/SecureWorks/ReleaseNotes/5_0_8.md new file mode 100644 index 000000000000..868e637918fb --- /dev/null +++ b/Packs/SecureWorks/ReleaseNotes/5_0_8.md @@ -0,0 +1,3 @@ +#### Integrations +##### TaegisXDR v2 +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/SecureWorks/pack_metadata.json b/Packs/SecureWorks/pack_metadata.json index 092a131d8d27..acb42c7a8ea7 100644 --- a/Packs/SecureWorks/pack_metadata.json +++ b/Packs/SecureWorks/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Secureworks", "description": "Provides access to the Secureworks CTP and Taegis XDR systems", "support": "partner", - "currentVersion": "5.0.7", + "currentVersion": "5.0.8", "author": "Secureworks", "url": "https://ctpx.secureworks.com", "email": "support@secureworks.com", diff --git a/Packs/SingleConnect/Integrations/SingleConnect/SingleConnect.yml b/Packs/SingleConnect/Integrations/SingleConnect/SingleConnect.yml index a294976f6ea4..b1563b1effc1 100644 --- a/Packs/SingleConnect/Integrations/SingleConnect/SingleConnect.yml +++ b/Packs/SingleConnect/Integrations/SingleConnect/SingleConnect.yml @@ -269,7 +269,7 @@ script: - contextPath: SingleConnect.SapmAccount.groupFullPath description: The full path of the SAPM group that the account is under. type: String - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 runonce: false script: '-' subtype: python3 diff --git a/Packs/SingleConnect/ReleaseNotes/1_0_15.md b/Packs/SingleConnect/ReleaseNotes/1_0_15.md new file mode 100644 index 000000000000..aab381f2b3a7 --- /dev/null +++ b/Packs/SingleConnect/ReleaseNotes/1_0_15.md @@ -0,0 +1,3 @@ +#### Integrations +##### Single Connect +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/SingleConnect/pack_metadata.json b/Packs/SingleConnect/pack_metadata.json index ad74a1356567..1d463af0dffa 100644 --- a/Packs/SingleConnect/pack_metadata.json +++ b/Packs/SingleConnect/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Single Connect", "description": "Single Connect enables enterprises to remove static passwords stored in applications by instead keeping passwords in a secure password vault. It secures access to passwords through token-based authentication", "support": "partner", - "currentVersion": "1.0.14", + "currentVersion": "1.0.15", "author": "Krontech", "url": "https://kron.com.tr/en/single-connect", "email": "", diff --git a/Packs/Stairwell/Integrations/Inception/Inception.yml b/Packs/Stairwell/Integrations/Inception/Inception.yml index a84d7805f826..aacb8cb2bb21 100644 --- a/Packs/Stairwell/Integrations/Inception/Inception.yml +++ b/Packs/Stairwell/Integrations/Inception/Inception.yml @@ -48,7 +48,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 fromversion: 6.5.0 tests: - No tests (auto formatted) diff --git a/Packs/Stairwell/ReleaseNotes/1_0_16.md b/Packs/Stairwell/ReleaseNotes/1_0_16.md new file mode 100644 index 000000000000..d927a7af91c9 --- /dev/null +++ b/Packs/Stairwell/ReleaseNotes/1_0_16.md @@ -0,0 +1,3 @@ +#### Integrations +##### Stairwell Inception +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/Stairwell/pack_metadata.json b/Packs/Stairwell/pack_metadata.json index daf876c2047a..7d3e9c257c19 100644 --- a/Packs/Stairwell/pack_metadata.json +++ b/Packs/Stairwell/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Stairwell", "description": "Inception is a security intelligence engine that automates the continuous capture, storage, and analysis of executable files.", "support": "partner", - "currentVersion": "1.0.15", + "currentVersion": "1.0.16", "author": "Stairwell", "url": "https://www.stairwell.com", "email": "support@stairwell.com", diff --git a/Packs/Tessian/Integrations/Tessian/Tessian.yml b/Packs/Tessian/Integrations/Tessian/Tessian.yml index 13b8a7995c45..ce7b0f88c93a 100644 --- a/Packs/Tessian/Integrations/Tessian/Tessian.yml +++ b/Packs/Tessian/Integrations/Tessian/Tessian.yml @@ -110,7 +110,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/python3:3.10.13.86272 + dockerimage: demisto/python3:3.10.13.87159 fromversion: 6.10.0 tests: - No tests (auto formatted) diff --git a/Packs/Tessian/ReleaseNotes/1_0_4.md b/Packs/Tessian/ReleaseNotes/1_0_4.md new file mode 100644 index 000000000000..7889c09e5d97 --- /dev/null +++ b/Packs/Tessian/ReleaseNotes/1_0_4.md @@ -0,0 +1,3 @@ +#### Integrations +##### Tessian +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/Tessian/pack_metadata.json b/Packs/Tessian/pack_metadata.json index 8a92a622c6e2..192f113972a9 100644 --- a/Packs/Tessian/pack_metadata.json +++ b/Packs/Tessian/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Tessian", "description": "Tessian's complete cloud email security platform defends customers against advanced phishing threats, and protects their sensitive data on email.", "support": "partner", - "currentVersion": "1.0.3", + "currentVersion": "1.0.4", "author": "Tessian", "url": "", "email": "support@tessian.com", From 07da899fcadd6601d5fe98a9c137f718c2f3be31 Mon Sep 17 00:00:00 2001 From: Dan Tavori <38749041+dantavori@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:55:11 +0200 Subject: [PATCH 059/272] fix base client execution metrics (#33044) * fix base client execution metrics * added test --- Packs/Base/ReleaseNotes/1_33_35.md | 6 ++++++ .../CommonServerPython/CommonServerPython.py | 8 ++++++-- .../CommonServerPython/CommonServerPython_test.py | 15 +++++++++++++++ Packs/Base/pack_metadata.json | 2 +- 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 Packs/Base/ReleaseNotes/1_33_35.md diff --git a/Packs/Base/ReleaseNotes/1_33_35.md b/Packs/Base/ReleaseNotes/1_33_35.md new file mode 100644 index 000000000000..699fb5330fc2 --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_33_35.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### CommonServerPython + +- Fixed an issue where, in some cases, an AttributeError was raised during the destruction of a BaseClient object. diff --git a/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py b/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py index fc52b1e430d5..1d636774f7c8 100644 --- a/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py +++ b/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py @@ -9226,9 +9226,13 @@ def client_error_handler(self, res): def _return_execution_metrics_results(self): """ Returns execution metrics results. + Might raise an AttributeError exception if execution_metrics is not initialized. """ - if self.execution_metrics.metrics: - return_results(cast(CommandResults, self.execution_metrics.metrics)) + try: + if self.execution_metrics.metrics: + return_results(cast(CommandResults, self.execution_metrics.metrics)) + except AttributeError: + pass def batch(iterable, batch_size=1): diff --git a/Packs/Base/Scripts/CommonServerPython/CommonServerPython_test.py b/Packs/Base/Scripts/CommonServerPython/CommonServerPython_test.py index f320123f3cc8..5786abb9feb8 100644 --- a/Packs/Base/Scripts/CommonServerPython/CommonServerPython_test.py +++ b/Packs/Base/Scripts/CommonServerPython/CommonServerPython_test.py @@ -3355,6 +3355,21 @@ def test_http_request_no_execution_metrics_results(cls, requests_mock, mocker): del client demisto_results_mock.assert_not_called + def test_base_client_subclass_without_execution_metrics_initialized(self): + """ + Given: A BaseClient object and a subclass of it that does not initialize execution_metrics + When: deleting the client object + Then: Ensure the deletion does not raise any exception + """ + from CommonServerPython import BaseClient + + class Client(BaseClient): + def __init__(self): + pass + + client = Client() + del client + @pytest.mark.skipif(not IS_PY3, reason='test not supported in py2') def test_http_request_params_parser_quote(self, requests_mock): """ diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index 6b58869f6b55..c96905e352c6 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.33.34", + "currentVersion": "1.33.35", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", From 47e780b603ba83a103ef8ea4508a31031cc90008 Mon Sep 17 00:00:00 2001 From: samuelFain <65926551+samuelFain@users.noreply.github.com> Date: Wed, 21 Feb 2024 13:53:30 +0200 Subject: [PATCH 060/272] [pre commit] Update coverage-analyze hook (#33035) * change coverage-analyze to coverage-pytest-analyze * Update hook * Update .pre-commit-config_template.yaml --- .pre-commit-config_template.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config_template.yaml b/.pre-commit-config_template.yaml index 711b2748d49b..d58b53d9551c 100644 --- a/.pre-commit-config_template.yaml +++ b/.pre-commit-config_template.yaml @@ -204,8 +204,8 @@ repos: pass_filenames: false needs: - pytest-in-docker - - id: coverage-analyze - name: coverage-analyze + - id: coverage-pytest-analyze + name: coverage-pytest-analyze entry: demisto-sdk coverage-analyze description: Running demisto-sdk coverage-analyze and showing a coverage report. language: system From 31845e438f93a099509d6ddc9e842a1741c9a1d3 Mon Sep 17 00:00:00 2001 From: merit-maita <49760643+merit-maita@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:58:44 +0200 Subject: [PATCH 061/272] Teams docs (#32949) * updated readme * edited description * added rn * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> * lr * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams_description.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * added unittest --------- Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- .../MicrosoftTeams_description.md | 2 +- .../Integrations/MicrosoftTeams/README.md | 145 ++++++++---------- Packs/MicrosoftTeams/ReleaseNotes/1_4_52.md | 6 + Packs/MicrosoftTeams/pack_metadata.json | 2 +- 4 files changed, 74 insertions(+), 81 deletions(-) create mode 100644 Packs/MicrosoftTeams/ReleaseNotes/1_4_52.md diff --git a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams_description.md b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams_description.md index 5170310217b0..97bcaecce186 100644 --- a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams_description.md +++ b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams_description.md @@ -1,5 +1,5 @@ Use the Microsoft Teams integration to send messages and notifications to your team members and create meetings. -Note: the integration is supported in Cortex XSOAR 8 without using an engine. +Note: The integration is supported in Cortex XSOAR 8 and Cortex XSIAM without using an engine. To create an instance of the Microsoft Teams integration in Cortex XSOAR, complete the following: diff --git a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md index f097d239802c..8f4389b61c0d 100644 --- a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md +++ b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/README.md @@ -2,15 +2,12 @@ Use the Microsoft Teams integration to send messages and notifications to your t This integration was integrated and tested with version 1.0 of Microsoft Teams. **Note:** -- This integration is supported in Cortex XSOAR 8 and up without using an engine. +- This integration is supported in Cortex XSOAR 8 and up and Cortex XSIAM without using an engine. - The integration has the ability to run built-in Cortex XSOAR commands, through a mirrored channel. Make sure to pass the command in the chat exactly as typed in the CORTEX XSOAR CLI. For example: `!DeleteContext all=yes`. Use the command `mirror-investigation` to mirror/create a mirrored channel. - For use cases where it is only needed to send messages to a specific channel, we recommend checking the [Microsoft Teams via Webhook Integration](https://xsoar.pan.dev/docs/reference/integrations/microsoft-teams-via-webhook), which has a simpler setup. ## Integration Architecture Data is passed between Microsoft Teams and Cortex XSOAR through the bot that you will configure in Microsoft Teams. A webhook (that you will configure) receives the data from Teams and passes it to the messaging endpoint. The web server on which the integration runs in Cortex XSOAR listens to the messaging endpoint and processes the data from Teams. You can use an engine for communication between Teams and the Cortex XSOAR server. In order to mirror messages from Teams to Cortex XSOAR, the bot must be mentioned, using the @ symbol, in the message. -- *Note* - In order to avoid mentioning the bot, if this was previously configured without adding the Bot ID, repeat the authentication flow and pay particular attention to the following steps: - * Step 14 in [Using the App Studio](#using-the-app-studio). - * Step 5 in [Using the Developer Portal](#using-the-developer-portal-1). The web server for the integration runs within a long-running Docker container. Cortex XSOAR maps the Docker port to which the server listens, to the host port (to which Teams posts messages). For more information, see [our documentation](https://xsoar.pan.dev/docs/integrations/long-running#invoking-http-integrations-via-cortex-xsoar-servers-route-handling) and [Docker documentation](https://docs.docker.com/config/containers/container-networking/). ### Protocol Diagram @@ -20,7 +17,7 @@ The web server for the integration runs within a long-running Docker container. - The messaging endpoint must be one of the following: - the URL of the Cortex XSOAR server, including the configured port - the Cortex XSOAR rerouting URL that you've defined for your Microsoft Teams instance (see the [Using Cortex XSOAR rerouting](#1-using-cortex-xsoar-rerouting) section for more details) - - or a proxy that redirects the messages received from Teams to the Cortex XSOAR server (see the [Using NGINX as reverse proxy](#2-using-nginx-as-reverse-proxy) section for more details) + - a proxy that redirects the messages received from Teams to the Cortex XSOAR or Cortex XSIAM server (see the [Using NGINX as reverse proxy](#2-using-nginx-as-reverse-proxy) section for more details) - Microsoft Teams will send events to the messaging endpoints via HTTPS request, which means the messaging endpoint must be accessible for Microsoft Teams to reach to it. As follows, the messaging endpoint can not contain private IP address or any DNS that will block the request from Microsoft Teams. In order to verify that the messaging endpoint is open as expected, you can surf to the messaging endpoint from a browser in an environment which is disconnected from the Cortex XSOAR environment. - It's important that the port is opened for outside communication and that the port is not being used, meaning that no service is listening on it. Therefore, the default port, 443, should not be used. @@ -53,16 +50,16 @@ In order to verify that the messaging endpoint is open as expected, you can surf ## Setup Examples -### 1. Using Cortex XSOAR rerouting -In this configuration, we will use Cortex XSOAR functionality, which reroutes HTTPS requests that hit the default port (443) to the web server that the integration spins up. +### 1. Using Cortex XSOAR or Cortex XSIAM rerouting +In this configuration, we will use Cortex XSOAR/Cortex XSIAM functionality, which reroutes HTTPS requests that hit the default port (443) to the web server that the integration spins up. The messaging endpoint needs to be: For Cortex XSOAR version 6.x: `/instance/execute/`, e.g., `https://my.demisto.live/instance/execute/teams`. -For Cortex XSOAR version 8: `https://ext-/xsoar/instance/execute/`, e.g., `https://ext-my.demisto.live/xsoar/instance/execute/teams`. +For Cortex XSOAR version 8 and XSIAM: `https://ext-/xsoar/instance/execute/`, e.g., `https://ext-my.demisto.live/xsoar/instance/execute/teams`. -The integration instance name, `teams` in this example, needs to be configured in the [Configure Microsoft Teams on Cortex XSOAR](#configure-microsoft-teams-on-cortex-xsoar) step. +The integration instance name, `teams` in this example, needs to be configured in the [Configure Microsoft Teams on Cortex XSOAR](#configure-microsoft-teams-on-cortex-xsoar) step. Make sure to set the instance name in all lowercase letters and as one word. The port to be configured in [Configure Microsoft Teams on Cortex XSOAR](#configure-microsoft-teams-on-cortex-xsoar) step should be any available port that is not used by another service. @@ -73,8 +70,8 @@ In addition, make sure ***Instance execute external*** is enabled (for Cortex XS ### 2. Using NGINX as reverse proxy -In this configuration, the inbound connection, from Microsoft Teams to Cortex XSOAR, goes through a reverse proxy (e.g. NGINX) which relays the HTTPS requests posted from Microsoft Teams -to the Cortex XSOAR server on HTTP. +In this configuration, the inbound connection, from Microsoft Teams to Cortex XSOAR/Cortex XSIAM, goes through a reverse proxy (e.g., NGINX) which relays the HTTPS requests posted from Microsoft Teams +to the Cortex XSOAR/Cortex XSIAM server on HTTP. On NGINX, configure the following: - SSL certificate under `ssl_certificate` and `ssl_certificate_key` @@ -89,8 +86,8 @@ The port (`7000` in this example), to which the reverse proxy should forward the ![image](https://github.com/demisto/content/raw/fa322765a440f8376bbf7ac85f0400beb720f712/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/doc_files/InstanceConfig7000.png) ### 3. Using Apache reverse proxy and Cortex XSOAR engine -In this configuration, the inbound connection, from Microsoft Teams to Cortex XSOAR, goes through a reverse proxy (e.g., [Apache](https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html)) and possibly a load balancer, which relays the HTTPS requests posted from Microsoft Teams -to a Cortex XSOAR engine, which can be put in a DMZ, on HTTP. +In this configuration, the inbound connection, from Microsoft Teams to Cortex XSOAR/Cortex XSIAM, goes through a reverse proxy (e.g., [Apache](https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html)) and possibly a load balancer, which relays the HTTPS requests posted from Microsoft Teams +to a Cortex XSOAR/Cortex XSIAM engine, which can be put in a DMZ, on HTTP. The port (`7000` in this example), to which the reverse proxy should forward the traffic on HTTP, should be the same port you specify in the integration instance configuration, as the web server the integration spins up, listens on that port. @@ -102,7 +99,7 @@ The port (`7000` in this example), to which the reverse proxy should forward the ### 4. Using Cloudflare In this configuration, we will use [Cloudflare proxy](https://support.cloudflare.com/hc/en-us/articles/360039824852-Cloudflare-and-the-Cloud-Conceptual-overview-videos). -The messaging endpoint should be the Cortex XSOAR URL, which need to be hosted on Cloudflare, with the port to which Cloudflare proxy directs the HTTPS traffic, e.g. `https://mysite.com:8443` +The messaging endpoint should be the Cortex XSOAR/Cortex XSIAM URL, which needs to be hosted on Cloudflare, with the port to which Cloudflare proxy directs the HTTPS traffic, e.g., `https://mysite.com:8443` In the [Configure Microsoft Teams on Cortex XSOAR](#configure-microsoft-teams-on-cortex-xsoar) step, the following need to be configured: - The port selected above. @@ -131,19 +128,17 @@ The information in this video is for Cortex XSOAR 6 only. ## Prerequisites -Before you can create an instance of the Microsoft Teams integration in Cortex XSOAR, you need to complete the following procedures. +Before you can create an instance of the Microsoft Teams integration in Cortex XSOAR/Cortex XSIAM, you need to complete the following procedures. 1. [Create the Demisto Bot in Microsoft Teams](#create-the-demisto-bot-in-microsoft-teams) 2. [Grant the Demisto Bot Permissions in Microsoft Graph](#grant-the-demisto-bot-permissions-in-microsoft-graph) -3. [Configure Microsoft Teams on Cortex XSOAR](#configure-microsoft-teams-on-cortex-xsoar) +3. [Configure Microsoft Teams on Cortex XSOAR or Cortex XSIAM](#configure-microsoft-teams-on-cortex-xsoar) 4. [Add the Demisto Bot to a Team](#add-the-demisto-bot-to-a-team) -#### *Note:* Microsoft App Studio is being phased out and will be deprecated on January 1, 2022. It is replaced by Microsoft Developer Portal. Steps 1 and 4 differ if using the App Studio or the Developer Portal. - ### Create the Demisto Bot in Microsoft Teams -#### Creating the Demisto Bot for Production environment using Microsoft Azure Portal (Recommended) +#### Creating the Demisto Bot using Microsoft Azure Portal 1. Navigate to the [Create an Azure Bot page](https://portal.azure.com/#create/Microsoft.AzureBot). 2. In the Bot Handle field, type **Demisto Bot**. 3. Fill in the required Subscription and Resource Group, relevant links: [Subscription](https://learn.microsoft.com/en-us/azure/cost-management-billing/manage/create-subscription), [Resource Groups](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/manage-resource-groups-portal). @@ -161,26 +156,17 @@ Before you can create an instance of the Microsoft Teams integration in Cortex X Note: in step 5, if you choose **Use existing app registration**, make sure to delete the previous created bot with the same app id, remove it from the team it was added to as well. -#### Creating the Demisto Bot for development environment using the Developer Portal (Recommended to use `Azure portal` method mentioned above, this method will be removed soon) -1. Navigate to the [Tools in the Microsoft Developer Portal](https://dev.teams.microsoft.com/tools). -2. Navigate to **Bot management**. -3. Click the **+New Bot** button. -4. Fill in `Demisto Bot` in the prompt, click the *Add* button, and wait a few seconds until the bot is created. -5. Record the **Bot ID** of `Demisto Bot` for the next steps. -6. Click on the line where `Demisto Bot` shows under the **Bot Name**. -![image](./doc_files/appentry.png) -7. Navigate to **Configure** and fill in the **Bot endpoint address**. -8. Navigate to **Client Secrets** and click the **Add a client secret for your bot** button, and wait a few seconds to allow the secret to be generated. -9. Store the generated secret securely for the next steps. +### Grant the Demisto Bot Permissions in Microsoft Graph -### In order to connect to the Azure Network Security Groups use one of the following methods: +In order to connect to Microsoft Teams use one of the following authentication methods: 1. *Client Credentials Flow* 2. *Authorization Code Flow* -### Client Credentials Flow -#### Grant the Demisto Bot Permissions in Microsoft Graph +##### Client Credentials Flow + +Note: [The chat commands](#chat-commands) are only supported when using the `Authorization Code flow`. 1. Go to your Microsoft Azure portal, and from the left navigation pane select **Azure Active Directory > App registrations**. 2. Search for and click **Demisto Bot**. @@ -197,30 +183,27 @@ Note: in step 5, if you choose **Use existing app registration**, make sure to d 5. Verify that all permissions were added, and click **Grant admin consent for Demisto**. 6. When prompted to verify granting permissions, click **Yes**, and verify that permissions were successfully added. -#### Authentication Using the Client Credentials Flow - -1. Choose the 'Client Credentials' option in the **Authentication Type** parameter. -2. Enter your Client/Application ID in the **Bot ID** parameter. -3. Enter your Client Secret in the **Bot Password** parameter. -4. Save the instance. +#### Authorization Code Flow -### Authorization Code Flow -#### Grant the Demisto Bot Permissions in Microsoft Graph +Note: The [microsoft-teams-ring-user](https://learn.microsoft.com/en-us/graph/api/application-post-calls?view=graph-rest-1.0&tabs=http) command is only supported when using the `Client Credentials flow` due to a limitation in Microsoft's permissions system. 1. Go to your Microsoft Azure portal, and from the left navigation pane select **Azure Active Directory > App registrations**. 2. Search for and click **Demisto Bot**. 3. Click **API permissions > Add a permission > Microsoft Graph > Application permissions**. 4. For the following permissions, search for the permission, select the checkbox and click **Add permissions**. - ##### Required Application Permissions: + ###### Required Application Permissions: - User.Read.All - Group.ReadWrite.All - OnlineMeetings.ReadWrite.All - ChannelMember.ReadWrite.All - Channel.Create - Chat.Create + - TeamsAppInstallation.ReadWriteSelfForChat.All + - TeamsAppInstallation.ReadWriteForChat.All + - AppCatalog.Read.All - ##### Required Delegated Permissions: + ###### Required Delegated Permissions: - OnlineMeetings.ReadWrite - ChannelMessage.Send - Chat.ReadWrite @@ -230,6 +213,8 @@ Note: in step 5, if you choose **Use existing app registration**, make sure to d - ChannelSettings.ReadWrite.All - ChatMember.ReadWrite - Chat.Create + - TeamsAppInstallation.ReadWriteForChat + - TeamsAppInstallation.ReadWriteSelfForChat 5. Verify that all permissions were added, and click **Grant admin consent for Demisto**. 6. When prompted to verify granting permissions, click **Yes**, and verify that permissions were successfully added. 7. Click **Expose an API** and add **Application ID URI** @@ -240,20 +225,6 @@ Note: in step 5, if you choose **Use existing app registration**, make sure to d - ChannelMember.Read.All 9. Click **Authentication > Platform configurations > Add a platform.** Choose **Web** and add Redirect URIs: https://login.microsoftonline.com/common/oauth2/nativeclient -#### Authentication Using the Authorization Code Flow - -1. Choose the 'Authorization Code' option in the **Authentication Type** parameter. -2. Enter your Client/Application ID in the **Bot ID** parameter. -3. Enter your Client Secret in the **Bot Password** parameter. -4. Enter your Application redirect URI in the **Application redirect URI** parameter. -5. Copy the following URL and replace the **TENANT_ID**, **CLIENT_ID** and **REDIRECT_URI** with your own client ID and redirect URI, accordingly. -https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/authorize?response_type=code&response_mode=query&scope=offline_access%20https%3A%2F%2Fgraph.microsoft.com%2F.default&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&state=12345. When prompted, accept the Microsoft authorization request for the required permissions. You will be automatically redirected to a link with the following structure: -```REDIRECT_URI?code=AUTH_CODE&state=12345&session_state=SESSION_STATE``` -6. Copy the **AUTH_CODE** (without the “code=” prefix) and paste it in your instance configuration under the **Authorization code** parameter. -7. Save the instance. -8. Run the ***!microsoft-teams-auth-test*** command. A 'Success' message should be printed to the War Room. - - ### Configure Microsoft Teams on Cortex XSOAR @@ -278,20 +249,39 @@ https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/authorize?response_type= | Disable Automatic Notifications | Whether to disable automatic notifications to the configured notifications channel. | False | | Allow external users to create incidents via direct message | | False | | The header of an external form hyperlink. | | False | - | Trust any certificate (not secure) | Do not check for Cortex XSOAR version 8 | False | + | Trust any certificate (not secure) | Do not check for Cortex XSOAR version 8 and Cortex XSIAM. | False | | Use system proxy settings | | False | - | Long running instance | | False | + | Long running instance | | True | | Listen port, e.g., 7000 (Required for investigation mirroring and direct messages) | longRunningPort | False | | Incident type | Incident type. | False | 4. Click **Test** to validate the URLs, token, and connection. 5. Click the **Save & exit** button. +#### Configuring the instance with the chosen authentication flow + +##### Authentication Using the Client Credentials Flow + +1. Choose the 'Client Credentials' option in the *Authentication Type* parameter. +2. Enter your Client/Application ID in the *Bot ID* parameter. +3. Enter your Client Secret in the *Bot Password* parameter. +4. Save the instance. + +##### Authentication Using the Authorization Code Flow + +1. Choose the 'Authorization Code' option in the *Authentication Type* parameter. +2. Enter your Client/Application ID in the *Bot ID* parameter. +3. Enter your Client Secret in the *Bot Password* parameter. +4. Enter your Application redirect URI in the *Application redirect URI* parameter. +5. Run the ***!microsoft-teams-generate-login-url*** command in the War Room and follow the instructions. +6. Save the instance. +7. Run the ***!microsoft-teams-auth-test*** command. A 'Success' message should be printed to the War Room. + + ### Add the Demisto Bot to a Team -- Note: the following need to be done after configuring the integration on Cortex XSOAR (the previous step). +- Note: The following needs to be done after configuring the integration on Cortex XSOAR/Cortex XSIAM (the previous step). -#### Using the Developer Portal and Microsoft Azure Portal 1. Download the ZIP file located at the bottom of this article. 2. Uncompress the ZIP file. You should see 3 files (`manifest.json`, `color.png` and `outline.png`). 3. Open the `manifest.json` file that was extracted from the ZIP file. @@ -324,6 +314,7 @@ https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/authorize?response_type= ## Commands You can execute these commands from the Cortex XSOAR 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. + ### send-notification *** Sends a message to the specified teams. @@ -336,7 +327,7 @@ To mention a user in the message, add a semicolon ";" at the end of the user men ##### Required Permissions -`Group.Read.All` +`Group.ReadWrite.All` ##### Input @@ -363,9 +354,9 @@ Message was sent successfully. ### mirror-investigation *** -Mirrors the Cortex XSOAR investigation to the specified Microsoft Teams channel. Supports only standard channels. +Mirrors the Cortex XSOAR/Cortex XSIAM investigation to the specified Microsoft Teams channel. Supports only standard channels. -**Note**: Mirrored channels could be used to run Cortex XSOAR built-in commands. +**Note**: Mirrored channels could be used to run Cortex XSOAR/Cortex XSIAM built-in commands. ##### Base Command @@ -691,6 +682,9 @@ Retrieves a list of members from a channel. |--------------------------------------|----------------|--------------------------------------|------------------------------------------------------------------------------------------------------|------------|--------------|----------------------| | 359d2c3c-162b-414c-b2eq-386461e5l050 | test@gmail.com | pbae9ao6-01ql-249o-5me3-4738p3e1m941 | MmFiOWM3OTYtMjkwMi00NWY4LWI3MTItN2M1YTYzY2Y0MWM0IyNlZWY5Y2IzNi0wNmRlLTQ2OWItODdjZC03MGY0Y2JlMzJkMTQ= | owner | itayadmin | 0001-01-01T00:00:00Z | + +### Chat Commands + ### microsoft-teams-chat-create *** Creates a new chat. @@ -1078,18 +1072,10 @@ There is no context output for this command. >2. Copy the `AUTH_CODE` (without the `code=` prefix, and the `session_state` parameter) >and paste it in your instance configuration under the **Authorization code** parameter. > -## Running commands from Microsoft Teams -You can run Cortex XSOAR commands, according to the user permissions, from Microsoft Teams in a mirrored investigation channel. - -Note: Like every message in a mirrored channel, in order for it to be passed to the bot, the bot must be mentioned. -In order to avoid mentioning the bot, if this was previously configured without adding the Bot ID, repeat the authentication flow and pay particular attention to the following steps: - * Step 14 in [Using the App Studio](#using-the-app-studio). - * Step 5 in [Using the Developer Portal](#using-the-developer-portal-1). -For example, in order to check the reputation of the IP address 8.8.8.8, run the following: `@Demisto Bot !ip ip=8.8.8.8` - -![image](https://raw.githubusercontent.com/demisto/content/c7d516e68459f04102fd31ebfadd6574d775f436/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/doc_files/cmd.png) +## Running commands from Microsoft Teams +You can run Cortex XSOAR/Cortex XSIAM commands, according to the user permissions, from Microsoft Teams in a mirrored investigation channel. ## Direct messages commands You can chat with the bot in direct messages in order to retrieve data (list incidents and tasks) and run operations (create incident and mirror an investigation) related to Cortex XSOAR. @@ -1109,7 +1095,8 @@ Note: To enrich an incident created via the Demisto BOT (`new incident` command) This probably means that there is a connection issue, and the web server does not intercept the HTTPS queries from Microsoft Teams. To troubleshoot: - 1. first verify the Docker container is up and running and publish the configured port to the outside world: + 1. Verify that the messaging endpoint is configured correctly according to the method you chose in the [Setup Examples](#setup-examples) step. + 2. Verify the Docker container is up and running and publish the configured port to the outside world: From the Cortex XSOAR / Cortex XSOAR engine machine run: `docker ps | grep teams` @@ -1123,15 +1110,15 @@ Note: To enrich an incident created via the Demisto BOT (`new incident` command) - From the Cortex XSOAR machine to localhost. - Note: The web server supports only POST method queries. - 2. If the cURL queries were sent successfully, you should see the following line in Cortex XSOAR logs: `Finished processing Microsoft Teams activity successfully`. + 3. If the cURL queries were sent successfully, you should see the following line in Cortex XSOAR logs: `Finished processing Microsoft Teams activity successfully`. - 3. If you're working with secured communication (HTTPS), make sure that you provided a valid certificate. + 4. If you're working with secured communication (HTTPS), make sure that you provided a valid certificate. (Not for Cortex XSOAR/Cortex XSIAM Rerouting ). 1. Run `openssl s_client -connect :443` . 2. Verify that the returned value of the `Verify return code` field is `0 (ok)`, otherwise, it's not a valid certificate. - 4. Try inserting your configured message endpoint in a browser and click **Enter**. If `Method Not Allowed` is returned, the endpoint is valid and ready to communicate, otherwise, it needs to be handled according to the returned error's message. + 5. Try inserting your configured message endpoint in a browser and click **Enter**. If `Method Not Allowed` is returned, the endpoint is valid and ready to communicate, otherwise, it needs to be handled according to the returned error's message. (Not for Cortex XSOAR 8 OR Cortex XSIAM). - 5. In some cases, a connection is not created between Teams and the messaging endpoint when adding a bot to the team. You can work around this problem by adding any member to the team the bot was added to (the bot should be already added to the team). This will trigger a connection and solve the issue. You can then remove the member that was added. + 6. In some cases, a connection is not created between Teams and the messaging endpoint when adding a bot to the team. You can work around this problem by adding any member to the team the bot was added to (the bot should be already added to the team). This will trigger a connection and solve the issue. You can then remove the member that was added. 2. If you see the following error message: `Error in API call to Microsoft Teams: [403] - UnknownError`, then it means the AAD application has insufficient permissions. diff --git a/Packs/MicrosoftTeams/ReleaseNotes/1_4_52.md b/Packs/MicrosoftTeams/ReleaseNotes/1_4_52.md new file mode 100644 index 000000000000..11864a7638b2 --- /dev/null +++ b/Packs/MicrosoftTeams/ReleaseNotes/1_4_52.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Teams + +- Documentation and metadata improvements. \ No newline at end of file diff --git a/Packs/MicrosoftTeams/pack_metadata.json b/Packs/MicrosoftTeams/pack_metadata.json index 440c13ba4b05..287d1fc63d90 100644 --- a/Packs/MicrosoftTeams/pack_metadata.json +++ b/Packs/MicrosoftTeams/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Teams", "description": "Send messages and notifications to your team members.", "support": "xsoar", - "currentVersion": "1.4.51", + "currentVersion": "1.4.52", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From a8c7174504c30306ecb8dcbaf7ed995d02bc6bb3 Mon Sep 17 00:00:00 2001 From: MLainer1 <93524335+MLainer1@users.noreply.github.com> Date: Wed, 21 Feb 2024 17:10:52 +0200 Subject: [PATCH 062/272] [bug] - threatconnect feed missing indicator type parser (#32993) * [bug] - threatconnect feed missing indicator type parser * test * rn * debug logs * DI * revert * precommit --- .../FeedThreatConnect/FeedThreatConnect.py | 22 +++++++++++-------- .../FeedThreatConnect/FeedThreatConnect.yml | 3 +-- .../FeedThreatConnect_test.py | 5 +++-- .../ReleaseNotes/2_1_20.json | 4 ++++ .../FeedThreatConnect/ReleaseNotes/2_1_20.md | 6 +++++ Packs/FeedThreatConnect/pack_metadata.json | 2 +- 6 files changed, 28 insertions(+), 14 deletions(-) create mode 100644 Packs/FeedThreatConnect/ReleaseNotes/2_1_20.json create mode 100644 Packs/FeedThreatConnect/ReleaseNotes/2_1_20.md diff --git a/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect.py b/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect.py index b46db363e844..04d69cfe444e 100644 --- a/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect.py +++ b/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect.py @@ -7,7 +7,6 @@ from contextlib import contextmanager from enum import Enum from math import ceil -from typing import Tuple # Local packages from CommonServerPython import * # noqa: E402 lgtm [py/polluting-import] @@ -29,7 +28,7 @@ INTEGRATION_NAME = 'ThreatConnect Feed' INTEGRATION_COMMAND_NAME = 'tc' INTEGRATION_CONTEXT_NAME = 'ThreatConnect' -COMMAND_OUTPUT = Tuple[str, Union[Dict[str, Any], List[Any]], Union[Dict[str, Any], List[Any]]] +COMMAND_OUTPUT = tuple[str, Union[Dict[str, Any], List[Any]], Union[Dict[str, Any], List[Any]]] INDICATOR_MAPPING_NAMES = { 'Address': FeedIndicatorType.IP, 'CIDR': FeedIndicatorType.CIDR, @@ -149,7 +148,6 @@ 'URL', 'ASN', 'CIDR', - 'Email Subject', 'Hashtag', 'Mutex', 'Registry Key', @@ -203,7 +201,7 @@ def create_types_query(params: dict, endpoint: str) -> str: raise DemistoException('No indicator type or group type were chosen, please choose at least one.') if endpoint == 'indicators': if 'All' in indicator_types: - return '' + types.extend(INDICATOR_TYPES) else: types.extend(indicator_types) else: @@ -236,7 +234,7 @@ def calculate_dbot_score(threat_assess_score: Optional[Union[int, str]] = None) def parse_indicator(indicator: Dict[str, str]) -> Dict[str, Any]: - """ Parsing indicator by indicators demisto convension. + """ Parsing indicator by indicators demisto convention. Args: indicator: Indicator as raw response. Returns: @@ -261,7 +259,8 @@ def parse_indicator(indicator: Dict[str, str]) -> Dict[str, Any]: def create_indicator_fields(indicator, indicator_type): """Creating an indicator fields from a raw indicator""" params = demisto.params() - indicator_fields_mapping = TC_INDICATOR_TO_XSOAR_INDICATOR[indicator_type] + indicator_fields_mapping = TC_INDICATOR_TO_XSOAR_INDICATOR.get(indicator_type, {}) + fields: dict = {} for indicator_key, xsoar_indicator_key in indicator_fields_mapping.items(): @@ -415,7 +414,7 @@ def module_test_command(client: Client, args): # pragma: no cover # noqa return_error(str(e)) -def fetch_indicators_command(client: Client, params: dict, last_run: dict) -> Tuple[ +def fetch_indicators_command(client: Client, params: dict, last_run: dict) -> tuple[ List[Dict[str, Any]], List[Dict[str, Any]]]: # noqa # pragma: no cover """ Fetch indicators from ThreatConnect @@ -581,8 +580,12 @@ def get_indicators_command(client: Client, args: dict) -> dict: # type: ignore types = argToList(args.get("indicator_type")) query = '' - if types and 'All' not in types: - query = 'AND typeName IN ("' + '","'.join(types) + '")' + + if types: + if 'All' in types: + query = 'AND typeName IN ("' + '","'.join(INDICATOR_TYPES) + '")' + else: + query = 'AND typeName IN ("' + '","'.join(types) + '")' tql = active_only + confidence + threat_score + confidence + owners + query tql = tql.replace('AND ', '', 1) @@ -604,6 +607,7 @@ def get_indicators_command(client: Client, args: dict) -> dict: # type: ignore t=t, removeNull=True) # type: ignore # noqa return readable_output, {}, list(response) # type: ignore + return {} def get_owners_command(client: Client, args: dict) -> COMMAND_OUTPUT: # pragma: no cover diff --git a/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect.yml b/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect.yml index ce02ce8269df..dafc994daa67 100644 --- a/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect.yml +++ b/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect.yml @@ -99,7 +99,6 @@ configuration: - URL - ASN - CIDR - - EmailSubject - Hashtag - Mutex - Registry Key @@ -237,7 +236,7 @@ script: name: tc-get-indicators - description: Gets available indicators owners. name: tc-get-owners - dockerimage: demisto/python3:3.10.13.84405 + dockerimage: demisto/python3:3.10.13.87159 feed: true runonce: false script: '-' diff --git a/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect_test.py b/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect_test.py index 914308b7f8cf..1eb470608971 100644 --- a/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect_test.py +++ b/Packs/FeedThreatConnect/Integrations/FeedThreatConnect/FeedThreatConnect_test.py @@ -6,7 +6,7 @@ def load_json_file(path): - with open(path, 'r') as _json_file: + with open(path) as _json_file: return json.load(_json_file) @@ -38,7 +38,8 @@ def test_create_or_query(): @pytest.mark.parametrize("params, expected_result, endpoint", [({'indicator_active': False, "indicator_type": ['All'], - 'createRelationships': False, "confidence": 0, "threat_assess_score": 0}, '', 'indicators'), + 'createRelationships': False, "confidence": 0, "threat_assess_score": 0}, + 'typeName IN ("EmailAddress","File","Host","URL","ASN","CIDR","Hashtag","Mutex","Registry Key","User Agent","Address")', 'indicators'), # noqa: E501 ({'indicator_active': True, "group_type": ['File'], 'createRelationships': False, "confidence": 0, "threat_assess_score": 0}, 'typeName IN ("File")', 'groups'), diff --git a/Packs/FeedThreatConnect/ReleaseNotes/2_1_20.json b/Packs/FeedThreatConnect/ReleaseNotes/2_1_20.json new file mode 100644 index 000000000000..b8dc5d29b59c --- /dev/null +++ b/Packs/FeedThreatConnect/ReleaseNotes/2_1_20.json @@ -0,0 +1,4 @@ +{ + "breakingChanges": true, + "breakingChangesNotes": "The *EmailSubject* option was removed from the *Indicator Types* feed parameter." +} \ No newline at end of file diff --git a/Packs/FeedThreatConnect/ReleaseNotes/2_1_20.md b/Packs/FeedThreatConnect/ReleaseNotes/2_1_20.md new file mode 100644 index 000000000000..a668e536d124 --- /dev/null +++ b/Packs/FeedThreatConnect/ReleaseNotes/2_1_20.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### ThreatConnect Feed +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. +- Fixed an issue where selecting indicators of type *EmailSubject* to pull caused an error. This type is no longer supported. diff --git a/Packs/FeedThreatConnect/pack_metadata.json b/Packs/FeedThreatConnect/pack_metadata.json index e82f6458e06c..b40d22f0d378 100644 --- a/Packs/FeedThreatConnect/pack_metadata.json +++ b/Packs/FeedThreatConnect/pack_metadata.json @@ -2,7 +2,7 @@ "name": "ThreatConnect Feed", "description": "ThreatConnect indicators feed for Cortex XSOAR TIM.", "support": "xsoar", - "currentVersion": "2.1.19", + "currentVersion": "2.1.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 1e9a4001c84e64d260392d41c8dcf9537bea86db Mon Sep 17 00:00:00 2001 From: Dean Arbel Date: Wed, 21 Feb 2024 17:18:48 +0200 Subject: [PATCH 063/272] [Sleep] Removed Polling in 6 (#33056) --- Packs/CommonScripts/ReleaseNotes/1_14_1.md | 6 ++++ Packs/CommonScripts/Scripts/Sleep/Sleep.js | 36 ++++++++++++---------- Packs/CommonScripts/pack_metadata.json | 2 +- 3 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 Packs/CommonScripts/ReleaseNotes/1_14_1.md diff --git a/Packs/CommonScripts/ReleaseNotes/1_14_1.md b/Packs/CommonScripts/ReleaseNotes/1_14_1.md new file mode 100644 index 000000000000..0264bf8275dd --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_14_1.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### Sleep + +Fixed an issue where sometimes tasks using Sleep did not continue as expected. diff --git a/Packs/CommonScripts/Scripts/Sleep/Sleep.js b/Packs/CommonScripts/Scripts/Sleep/Sleep.js index fdb524ccc18a..214141fa5c05 100644 --- a/Packs/CommonScripts/Scripts/Sleep/Sleep.js +++ b/Packs/CommonScripts/Scripts/Sleep/Sleep.js @@ -1,22 +1,24 @@ -pollingThreshold = 300; - -if (isDemistoVersionGE('8.4.0', 649563)) { - configThreshold = executeCommand('getServerConfig', {key: 'content.automation.sleep.threshold.seconds'}); - if (configThreshold[0] && !isError(configThreshold[0])) { - pollingThreshold = parseInt(configThreshold[0].Contents); +if (isDemistoVersionGE('8.0.0')) { + pollingThreshold = 300; + if (isDemistoVersionGE('8.4.0', 649563)) { + configThreshold = executeCommand('getServerConfig', {key: 'content.automation.sleep.threshold.seconds'}); + if (configThreshold[0] && !isError(configThreshold[0])) { + pollingThreshold = parseInt(configThreshold[0].Contents); + } } -} - -if (parseInt(args.seconds) >= pollingThreshold) { - // Polling implementation - return { - Type: entryTypes.note, - Contents: 'Sleep will complete in ' + args.seconds + ' seconds', - PollingCommand: 'Print', - NextRun: args.seconds + '', - PollingArgs: {value: 'Sleep completed in ' + args.seconds + ' seconds'}, - Timeout: String(parseInt(args.seconds) + 60) + + if (parseInt(args.seconds) >= pollingThreshold) { + // Polling implementation + return { + Type: entryTypes.note, + Contents: 'Sleep will complete in ' + args.seconds + ' seconds', + PollingCommand: 'Print', + NextRun: args.seconds + '', + PollingArgs: {value: 'Sleep completed in ' + args.seconds + ' seconds'}, + Timeout: String(parseInt(args.seconds) + 60) + } } + } // Sleep for the given number of seconds diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index 293d37cc7cee..1ec25f809949 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.14.0", + "currentVersion": "1.14.1", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 65ee944b854165e5f10f05cafa723d2c32c1befa Mon Sep 17 00:00:00 2001 From: Darya Koval <72339940+daryakoval@users.noreply.github.com> Date: Wed, 21 Feb 2024 20:04:11 +0200 Subject: [PATCH 064/272] ad-modify-user-ou adds backslash to CN (#31491) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update shift management scripts (#31130) * fixed the bug and added unit tests * updated docker image * RN * updated docker image * cr updates * EWS rule commands - MS graph python integrations (#30943) Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * MS IIS Update (#31132) * Updated ModelingRules * Updated ReleaseNotes * Updated ReleaseNotes * Anomali ThreatStream change DBot verdict from Benign to Unknown for Low Confidence Indicators (#30993) (#31151) * change DBot verdict from Benign to Unknown for Low Confidence Indicators Indicators found in Anomali that are below Confidence thresholds should be created as Unknown and not Benign. Anomali ThreatStream documentation regarding Confidence https://ui.threatstream.com/optic-doc/Content/Features/threat_model/Observables/details_indicator.htm Confidence - Confidence indicates the certainty that an observable exhibits or is connected to malicious behavior. If Anomali has indicators with low Confidence, that doesn't mean the indicator is Benign/Safe. It means Anomali is unsure that the indicator is Malicious and as such the more appropriate verdict in XSOAR should be Unknown. * add indicator_default_score param * changed values to Benign and Unknown * update README and RN * update RN * update docker set required to false * update docker * fix docs comments --------- Co-authored-by: zdrouse Co-authored-by: adi88d Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * generate empty junit files (#31153) * Update 1_6_0.json (#31164) * fix splunkpy splunk_submit_event_hec_command string issue (#30978) * fix splunkpy splunk_submit_event_hec_command string issue * test * add fix * update rn * [xsoar saas] - fix ports taxii2 e2e (#31163) * Hello world saas (#30901) * added a new incident field only for saas mp * added an incident field to xsoar_saas only for demonstration * format incident field * format incident field * added saas word to known words * version * merge with master * fixed the xsoar_saas end tag * Added tests to validate result * modified RN * pre commit changes * RN tags * ignoe long line * MS IIS README (#31158) * Updated README * Updated README * Fixes For IP Enrichment Playbooks (#31114) * Fixes For IP Enrichment Playbooks * RN * Removed the mapping rule from both playbooks. Updated the default value of the internal range playbook input according to RFC 1918. * Removed the value of 'UseReputationCommand' playbook input and fixes the YML files * Fixed RN * Removed the value set for the 'UseReputationCommand' sub-playbook input. Re-added the default value for 'UseReputationCommand' playbook input * skip ThreatStream-Test (#31172) * [transformers] Enhance to be more durable (#30897) [transformers] Enhance to be more durable * Fixes For 'Email Address Enrichment - Generic v2.1' (#31122) * Fixes For 'Email Address Enrichment - Generic v2.1' * Re-added the test playbook and marketplace configs to the playbook YML file * changed the 'domain' playbook input value * removed the 'domain' playbook input value and added RN * Fixed RN * Bump pack from version CommonPlaybooks to 2.4.34. --------- Co-authored-by: Content Bot * DisplayMappedFields - Fix dark mode text color (#31085) * removed the hardcoded color * removed the hardcoded color * update RN * update docker image * Bump pack from version CommonScripts to 1.12.48. * Unittest fixes * Bump pack from version CommonScripts to 1.12.49. * Unittest fixes * Bump pack from version CommonScripts to 1.12.50. * Bump pack from version CommonScripts to 1.12.51. * Bump pack from version CommonScripts to 1.12.52. * Bump pack from version CommonScripts to 1.12.53. --------- Co-authored-by: Content Bot * Updated the layout to exclude integration incident fields that are not pertinent to Vectra XDR (#31127) (#31182) Co-authored-by: Crest Data Systems <60967033+crestdatasystems@users.noreply.github.com> Co-authored-by: crestdatasystems Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> * Taxii2 server relationship bug (#31162) * [taxii2-server] - code fixes * bump rn * docker update * remove debug-log because may wanted * [ASM] EXPANDER-7096 - ASM Remediation Guidance Fields (#30955) (#31178) Co-authored-by: John <40349459+BigEasyJ@users.noreply.github.com> Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * Created pack for F5 BIG-IP APM (#31017) * Created pack for f5 apm * Added modeling rule files. * adding modeling rules and schema. * modified modeling rules * update yml file for modeling rule. * Update Packs/F5APM/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/F5APM/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/F5APM/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/F5APM/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/F5APM/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/F5APM/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * update readme. * Modified the read me file. --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * HelloWorld - delete old classifier (#31185) * Add support for is array for rep commands (#31169) * added support for isArray for python Xsoar supported reputation commands * added rn * Empty-Commit * python files fixes * fix docker issue * cr fixes * added logs and cache fix (#30577) * added logs and cache fix * Fixed another executeCommand results handling. * Updated docker image * Added rn * Update Packs/Phishing/ReleaseNotes/3_6_2.md Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> * Update Packs/Phishing/Scripts/FindDuplicateEmailIncidents/FindDuplicateEmailIncidents.py --------- Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> * Add support for is array for rep commands js (#31184) * JS files fixes * added rn * pre commit fixes * pre commit fixes * cr fixes * xsiam-avaya-siem-content-ciac-8502 (#31128) * init-pack * modeling-rules * add-docs * fix-pid-parsing * fix-README.md * Fixed For Endpoint Enrichment Playbooks (#31147) * Fixed For 'Endpoint Enrichment - Generic v2.1' Playbook * RN * RN * Fixes for Endpoint_Enrichment_-_Generic_v2.1_6_8 playbook * Bump pack from version CommonPlaybooks to 2.4.34. * Bump pack from version CommonPlaybooks to 2.4.35. * Fixed version for 'Endpoint Enrichment - Generic v2.1.6.8' playbook * Fixes for 'Endpoint Enrichment - Generic v2.1' playbook * Revert changes in 'Endpoint Enrichment - Generic v2.1' playbook --------- Co-authored-by: Content Bot * Update Docker Image To demisto/python3 (#31198) * Updated Metadata Of Pack DeveloperTools * Added release notes to pack DeveloperTools * Packs/DeveloperTools/Integrations/CreateIncidents/CreateIncidents.yml Docker image update * Updated Metadata Of Pack FlashpointFeed * Added release notes to pack FlashpointFeed * Packs/FlashpointFeed/Integrations/FlashpointFeed/FlashpointFeed.yml Docker image update * Updated Metadata Of Pack AbnormalSecurity * Added release notes to pack AbnormalSecurity * Packs/AbnormalSecurity/Integrations/AbnormalSecurity/AbnormalSecurity.yml Docker image update * Updated Metadata Of Pack FeedLOLBAS * Added release notes to pack FeedLOLBAS * Packs/FeedLOLBAS/Integrations/FeedLOLBAS/FeedLOLBAS.yml Docker image update * Updated Metadata Of Pack Hackuity * Added release notes to pack Hackuity * Packs/Hackuity/Integrations/Hackuity/Hackuity.yml Docker image update * Updated Metadata Of Pack Grafana * Added release notes to pack Grafana * Packs/Grafana/Integrations/Grafana/Grafana.yml Docker image update * Updated Metadata Of Pack Binalyze * Added release notes to pack Binalyze * Packs/Binalyze/Integrations/BinalyzeAIR/BinalyzeAIR.yml Docker image update * Updated Metadata Of Pack ServiceDeskPlus * Added release notes to pack ServiceDeskPlus * Packs/ServiceDeskPlus/Integrations/ServiceDeskPlus/ServiceDeskPlus.yml Docker image update * Updated Metadata Of Pack Oracle_IAM * Added release notes to pack Oracle_IAM * Packs/Oracle_IAM/Integrations/OracleIAM/OracleIAM.yml Docker image update * Updated Metadata Of Pack AccentureCTI * Added release notes to pack AccentureCTI * Packs/AccentureCTI/Integrations/ACTIIndicatorQuery/ACTIIndicatorQuery.yml Docker image update * Update Docker Image To demisto/boto3py3 (#31199) * Updated Metadata Of Pack SecurityIntelligenceServicesFeed * Added release notes to pack SecurityIntelligenceServicesFeed * Packs/SecurityIntelligenceServicesFeed/Integrations/SecurityIntelligenceServicesFeed/SecurityIntelligenceServicesFeed.yml Docker image update * Updated Metadata Of Pack AWS-IAM * Added release notes to pack AWS-IAM * Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml Docker image update * Updated Metadata Of Pack AWS-Route53 * Added release notes to pack AWS-Route53 * Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml Docker image update * Updated Metadata Of Pack AWS-AccessAnalyzer * Added release notes to pack AWS-AccessAnalyzer * Packs/AWS-AccessAnalyzer/Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml Docker image update * Updated Metadata Of Pack AWS-GuardDuty * Added release notes to pack AWS-GuardDuty * Packs/AWS-GuardDuty/Integrations/AWSGuardDutyEventCollector/AWSGuardDutyEventCollector.yml Docker image update * Packs/AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml Docker image update * Updated Metadata Of Pack AWS-SecurityHub * Added release notes to pack AWS-SecurityHub * Packs/AWS-SecurityHub/Integrations/AWSSecurityHubEventCollector/AWSSecurityHubEventCollector.yml Docker image update * Updated Metadata Of Pack Aws-SecretsManager * Added release notes to pack Aws-SecretsManager * Packs/Aws-SecretsManager/Integrations/AwsSecretsManager/AwsSecretsManager.yml Docker image update * Update Docker Image To demisto/armorblox (#31203) * Updated Metadata Of Pack Armorblox * Added release notes to pack Armorblox * Packs/Armorblox/Integrations/Armorblox/Armorblox.yml Docker image update * Update Docker Image To demisto/py3-tools (#31201) * Updated Metadata Of Pack Intezer * Added release notes to pack Intezer * Packs/Intezer/Integrations/IntezerV2/IntezerV2.yml Docker image update * Updated Metadata Of Pack Zabbix * Added release notes to pack Zabbix * Packs/Zabbix/Integrations/Zabbix/Zabbix.yml Docker image update * Updated Metadata Of Pack FeedMalwareBazaar * Added release notes to pack FeedMalwareBazaar * Packs/FeedMalwareBazaar/Integrations/MalwareBazaarFeed/MalwareBazaarFeed.yml Docker image update * Updated Metadata Of Pack FeedGCPWhitelist * Added release notes to pack FeedGCPWhitelist * Packs/FeedGCPWhitelist/Integrations/FeedGoogleIPRanges/FeedGoogleIPRanges.yml Docker image update * Updated Metadata Of Pack AccentureCTI_Feed * Added release notes to pack AccentureCTI_Feed * Packs/AccentureCTI_Feed/Integrations/ACTIIndicatorFeed/ACTIIndicatorFeed.yml Docker image update * Updated Metadata Of Pack SEKOIAIntelligenceCenter * Added release notes to pack SEKOIAIntelligenceCenter * Packs/SEKOIAIntelligenceCenter/Integrations/SEKOIAIntelligenceCenter/SEKOIAIntelligenceCenter.yml Docker image update * Updated Metadata Of Pack JARM * Added release notes to pack JARM * Packs/JARM/Integrations/JARM/JARM.yml Docker image update * Updated Metadata Of Pack CommonWidgets * Added release notes to pack CommonWidgets * Packs/CommonWidgets/Scripts/RSSWidget/RSSWidget.yml Docker image update * Updated Metadata Of Pack FiltersAndTransformers * Added release notes to pack FiltersAndTransformers * Packs/FiltersAndTransformers/Scripts/Jmespath/Jmespath.yml Docker image update * Update Docker Image To demisto/oci (#31202) * Updated Metadata Of Pack OracleCloudInfrastructure * Added release notes to pack OracleCloudInfrastructure * Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml Docker image update * Update Docker Image To demisto/accessdata (#31200) * Updated Metadata Of Pack Exterro * Added release notes to pack Exterro * Packs/Exterro/Integrations/Exterro/Exterro.yml Docker image update * Fix DS108 --------- Co-authored-by: israelpolishook * Update Docker Image To demisto/carbon-black-cloud (#31206) * Updated Metadata Of Pack CarbonBlackDefense * Added release notes to pack CarbonBlackDefense * Packs/CarbonBlackDefense/Integrations/CarbonBlackLiveResponseCloud/CarbonBlackLiveResponseCloud.yml Docker image update * Update Docker Image To demisto/taxii2 (#31205) * Updated Metadata Of Pack FeedUnit42v2 * Added release notes to pack FeedUnit42v2 * Packs/FeedUnit42v2/Integrations/FeedUnit42v2/FeedUnit42v2.yml Docker image update * Update Docker Image To demisto/crypto (#31204) * Updated Metadata Of Pack AzureKeyVault * Added release notes to pack AzureKeyVault * Packs/AzureKeyVault/Integrations/AzureKeyVault/AzureKeyVault.yml Docker image update * Updated Metadata Of Pack AzureSentinel * Added release notes to pack AzureSentinel * Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel.yml Docker image update * Updated Metadata Of Pack AzureDevOps * Added release notes to pack AzureDevOps * Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps.yml Docker image update * Updated Metadata Of Pack MicrosoftCloudAppSecurity * Added release notes to pack MicrosoftCloudAppSecurity * Packs/MicrosoftCloudAppSecurity/Integrations/MicrosoftCloudAppSecurity/MicrosoftCloudAppSecurity.yml Docker image update * Updated Metadata Of Pack AzureRiskyUsers * Added release notes to pack AzureRiskyUsers * Packs/AzureRiskyUsers/Integrations/AzureRiskyUsers/AzureRiskyUsers.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphGroups * Added release notes to pack MicrosoftGraphGroups * Packs/MicrosoftGraphGroups/Integrations/MicrosoftGraphGroups/MicrosoftGraphGroups.yml Docker image update * Updated Metadata Of Pack AzureSQLManagement * Added release notes to pack AzureSQLManagement * Packs/AzureSQLManagement/Integrations/AzureSQLManagement/AzureSQLManagement.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphAPI * Added release notes to pack MicrosoftGraphAPI * Packs/MicrosoftGraphAPI/Integrations/MicrosoftGraphAPI/MicrosoftGraphAPI.yml Docker image update * Updated Metadata Of Pack MicrosoftTeams * Added release notes to pack MicrosoftTeams * Packs/MicrosoftTeams/Integrations/MicrosoftTeamsManagement/MicrosoftTeamsManagement.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphApplications * Added release notes to pack MicrosoftGraphApplications * Packs/MicrosoftGraphApplications/Integrations/MicrosoftGraphApplications/MicrosoftGraphApplications.yml Docker image update * Update Docker Image To demisto/opnsense (#31208) * Updated Metadata Of Pack OPNSense * Added release notes to pack OPNSense * Packs/OPNSense/Integrations/OPNSense/OPNSense.yml Docker image update * Update Docker Image To demisto/auth-utils (#31207) * Updated Metadata Of Pack Cylance_Protect * Added release notes to pack Cylance_Protect * Packs/Cylance_Protect/Integrations/Cylance_Protect_v2/Cylance_Protect_v2.yml Docker image update * Updated Metadata Of Pack Zoom * Added release notes to pack Zoom * Packs/Zoom/Integrations/ZoomEventCollector/ZoomEventCollector.yml Docker image update * Updated Metadata Of Pack Silverfort * Added release notes to pack Silverfort * Packs/Silverfort/Integrations/Silverfort/Silverfort.yml Docker image update * Updated Metadata Of Pack AzureDataExplorer * Added release notes to pack AzureDataExplorer * Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer.yml Docker image update * Updated Metadata Of Pack MicrosoftManagementActivity * Added release notes to pack MicrosoftManagementActivity * Packs/MicrosoftManagementActivity/Integrations/MicrosoftManagementActivity/MicrosoftManagementActivity.yml Docker image update * Updated Metadata Of Pack Box * Added release notes to pack Box * Packs/Box/Integrations/BoxEventsCollector/BoxEventsCollector.yml Docker image update * Packs/Box/Integrations/BoxV2/BoxV2.yml Docker image update * Updated Metadata Of Pack Troubleshoot * Added release notes to pack Troubleshoot * Packs/Troubleshoot/Scripts/CertificatesTroubleshoot/CertificatesTroubleshoot.yml Docker image update * commit --------- Co-authored-by: israelpolishook * Update Docker Image To demisto/ippysocks-py3 (#31211) * Updated Metadata Of Pack Whois * Added release notes to pack Whois * Packs/Whois/Integrations/Whois/Whois.yml Docker image update * Update Docker Image To demisto/python3 (#31214) * Updated Metadata Of Pack QualysFIM * Added release notes to pack QualysFIM * Packs/QualysFIM/Integrations/QualysFIM/QualysFIM.yml Docker image update * Updated Metadata Of Pack FortiSIEM * Added release notes to pack FortiSIEM * Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.yml Docker image update * Updated Metadata Of Pack FreshworksFreshservice * Added release notes to pack FreshworksFreshservice * Packs/FreshworksFreshservice/Integrations/FreshworksFreshservice/FreshworksFreshservice.yml Docker image update * Updated Metadata Of Pack KnowBe4_KMSAT * Added release notes to pack KnowBe4_KMSAT * Packs/KnowBe4_KMSAT/Integrations/KnowBe4KMSATEventCollector/KnowBe4KMSATEventCollector.yml Docker image update * Packs/KnowBe4_KMSAT/Integrations/KnowBe4KMSAT/KnowBe4KMSAT.yml Docker image update * Updated Metadata Of Pack SafeNet_Trusted_Access * Added release notes to pack SafeNet_Trusted_Access * Packs/SafeNet_Trusted_Access/Integrations/SafeNetTrustedAccessEventCollector/SafeNetTrustedAccessEventCollector.yml Docker image update * Updated Metadata Of Pack DelineaSS * Added release notes to pack DelineaSS * Packs/DelineaSS/Integrations/DelineaSS/DelineaSS.yml Docker image update * Updated Metadata Of Pack Cryptocurrency * Added release notes to pack Cryptocurrency * Packs/Cryptocurrency/Integrations/Cryptocurrency/Cryptocurrency.yml Docker image update * Updated Metadata Of Pack PANOSPolicyOptimizer * Added release notes to pack PANOSPolicyOptimizer * Packs/PANOSPolicyOptimizer/Integrations/PANOSPolicyOptimizer/PANOSPolicyOptimizer.yml Docker image update * Updated Metadata Of Pack DeveloperTools * Added release notes to pack DeveloperTools * Packs/DeveloperTools/Integrations/CreateIncidents/CreateIncidents.yml Docker image update * Update Docker Image To demisto/boto3py3 (#31215) * Updated Metadata Of Pack SecurityIntelligenceServicesFeed * Added release notes to pack SecurityIntelligenceServicesFeed * Packs/SecurityIntelligenceServicesFeed/Integrations/SecurityIntelligenceServicesFeed/SecurityIntelligenceServicesFeed.yml Docker image update * Updated Metadata Of Pack AWS-IAM * Added release notes to pack AWS-IAM * Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml Docker image update * Updated Metadata Of Pack AWS-Route53 * Added release notes to pack AWS-Route53 * Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml Docker image update * Updated Metadata Of Pack AWS-AccessAnalyzer * Added release notes to pack AWS-AccessAnalyzer * Packs/AWS-AccessAnalyzer/Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml Docker image update * Updated Metadata Of Pack AWS-GuardDuty * Added release notes to pack AWS-GuardDuty * Packs/AWS-GuardDuty/Integrations/AWSGuardDutyEventCollector/AWSGuardDutyEventCollector.yml Docker image update * Packs/AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml Docker image update * Updated Metadata Of Pack AWS-SecurityHub * Added release notes to pack AWS-SecurityHub * Packs/AWS-SecurityHub/Integrations/AWSSecurityHubEventCollector/AWSSecurityHubEventCollector.yml Docker image update * Updated Metadata Of Pack Aws-SecretsManager * Added release notes to pack Aws-SecretsManager * Packs/Aws-SecretsManager/Integrations/AwsSecretsManager/AwsSecretsManager.yml Docker image update * Update Docker Image To demisto/accessdata (#31216) * Updated Metadata Of Pack Exterro * Added release notes to pack Exterro * Packs/Exterro/Integrations/Exterro/Exterro.yml Docker image update * Update Docker Image To demisto/oci (#31218) * Updated Metadata Of Pack OracleCloudInfrastructure * Added release notes to pack OracleCloudInfrastructure * Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml Docker image update * Update Docker Image To demisto/py3-tools (#31217) * Updated Metadata Of Pack Intezer * Added release notes to pack Intezer * Packs/Intezer/Integrations/IntezerV2/IntezerV2.yml Docker image update * Updated Metadata Of Pack Zabbix * Added release notes to pack Zabbix * Packs/Zabbix/Integrations/Zabbix/Zabbix.yml Docker image update * Updated Metadata Of Pack FeedMalwareBazaar * Added release notes to pack FeedMalwareBazaar * Packs/FeedMalwareBazaar/Integrations/MalwareBazaarFeed/MalwareBazaarFeed.yml Docker image update * Updated Metadata Of Pack FeedGCPWhitelist * Added release notes to pack FeedGCPWhitelist * Packs/FeedGCPWhitelist/Integrations/FeedGoogleIPRanges/FeedGoogleIPRanges.yml Docker image update * Updated Metadata Of Pack AccentureCTI_Feed * Added release notes to pack AccentureCTI_Feed * Packs/AccentureCTI_Feed/Integrations/ACTIIndicatorFeed/ACTIIndicatorFeed.yml Docker image update * Updated Metadata Of Pack SEKOIAIntelligenceCenter * Added release notes to pack SEKOIAIntelligenceCenter * Packs/SEKOIAIntelligenceCenter/Integrations/SEKOIAIntelligenceCenter/SEKOIAIntelligenceCenter.yml Docker image update * Updated Metadata Of Pack JARM * Added release notes to pack JARM * Packs/JARM/Integrations/JARM/JARM.yml Docker image update * Updated Metadata Of Pack Anomali_ThreatStream * Added release notes to pack Anomali_ThreatStream * Packs/Anomali_ThreatStream/Integrations/AnomaliThreatStreamv3/AnomaliThreatStreamv3.yml Docker image update * Updated Metadata Of Pack CommonWidgets * Added release notes to pack CommonWidgets * Packs/CommonWidgets/Scripts/RSSWidget/RSSWidget.yml Docker image update * Updated Metadata Of Pack FiltersAndTransformers * Added release notes to pack FiltersAndTransformers * Packs/FiltersAndTransformers/Scripts/Jmespath/Jmespath.yml Docker image update * CortexXDRIR-generic-polling (#31082) * - Added new playbook for quarantine_file - Old playbook deprecated - New image added * release notes added * - New playbook for _Retrieve_File_Playbook_v2 created - Old playbook _Retrieve_File_Playbook deprecated - Image was added * Release notes were added * Changed the name of the playbook * Readme file added * Added image * fixed image location in readme file * Update Packs/CortexXDR/Playbooks/Cortex_XDR_-_Retrieve_File_v2.yml Co-authored-by: Sasha Sokolovich <88268646+ssokolovich@users.noreply.github.com> * Bump pack from version CortexXDR to 6.0.4. * Removed unnecessary tests * Readme files were updated * Fixes for the playbooks * fixed Tests/conf.json file * image issue fixed * Added new images * Update Packs/CortexXDR/Playbooks/Cortex_XDR_-_Retrieve_File_Playbook_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/Cortex_XDR_-_Retrieve_File_Playbook_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/ReleaseNotes/6_0_4.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/ReleaseNotes/6_0_4.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/ReleaseNotes/6_0_4.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/ReleaseNotes/6_0_4.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/Cortex_XDR_-_Retrieve_File_Playbook_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/Cortex_XDR_-_quarantine_file_v2_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * PR fixes - new condition to check if the task finished successfully * release notes updated * image path fixed * Added new outputs for playbook * release notes updated * fix * readme files fixed * image issue * image issue * fix * fix * fix * fix * uploaded new playbook because of the image issue * fix for image issue * delete photo * fixes * test playbooks fixed * test playbooks removed --------- Co-authored-by: Sasha Sokolovich <88268646+ssokolovich@users.noreply.github.com> Co-authored-by: Content Bot Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Docker Image To demisto/crypto (#31219) * Updated Metadata Of Pack AzureKeyVault * Added release notes to pack AzureKeyVault * Packs/AzureKeyVault/Integrations/AzureKeyVault/AzureKeyVault.yml Docker image update * Updated Metadata Of Pack AzureSentinel * Added release notes to pack AzureSentinel * Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel.yml Docker image update * Updated Metadata Of Pack AzureDevOps * Added release notes to pack AzureDevOps * Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps.yml Docker image update * Updated Metadata Of Pack MicrosoftCloudAppSecurity * Added release notes to pack MicrosoftCloudAppSecurity * Packs/MicrosoftCloudAppSecurity/Integrations/MicrosoftCloudAppSecurity/MicrosoftCloudAppSecurity.yml Docker image update * Updated Metadata Of Pack AzureRiskyUsers * Added release notes to pack AzureRiskyUsers * Packs/AzureRiskyUsers/Integrations/AzureRiskyUsers/AzureRiskyUsers.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphGroups * Added release notes to pack MicrosoftGraphGroups * Packs/MicrosoftGraphGroups/Integrations/MicrosoftGraphGroups/MicrosoftGraphGroups.yml Docker image update * Updated Metadata Of Pack AzureSQLManagement * Added release notes to pack AzureSQLManagement * Packs/AzureSQLManagement/Integrations/AzureSQLManagement/AzureSQLManagement.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphAPI * Added release notes to pack MicrosoftGraphAPI * Packs/MicrosoftGraphAPI/Integrations/MicrosoftGraphAPI/MicrosoftGraphAPI.yml Docker image update * Updated Metadata Of Pack MicrosoftTeams * Added release notes to pack MicrosoftTeams * Packs/MicrosoftTeams/Integrations/MicrosoftTeamsManagement/MicrosoftTeamsManagement.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphApplications * Added release notes to pack MicrosoftGraphApplications * Packs/MicrosoftGraphApplications/Integrations/MicrosoftGraphApplications/MicrosoftGraphApplications.yml Docker image update * update pack ignore (#31193) * Slack event collector: fixed an issue where we get a Bad Request error (#31135) * fixed an issue where we get a Bad Request error. * pre-commit * added test * fixed Flake8 error * fixed cr comments * fixed cr comments * update Docker image * YR/Remove-fields-with-one-letter-DBotFindSimilarIncidents/XSUP-29299 (#31161) * fixes * code and test * remove Json feed from this pr * test * note * pre commit * RN * CR and Flake8 * format * pre commit * Fixes For 'URL Enrichment - Generic v2' Playbook (#31195) * Fixes For 'URL Enrichment - Generic v2' Playbook * RN * Bump pack from version CommonPlaybooks to 2.4.36. --------- Co-authored-by: Content Bot * F5 APM Remove XSIAM tags (#31221) * remove ls from test_e2e_results.sh (#31186) * [IsEmailAddressInternal] Fix an issue with **domain** argument (#31222) * First commit * Added RN * Update Packs/CommonScripts/ReleaseNotes/1_12_54.md Co-authored-by: Dean Arbel --------- Co-authored-by: Dean Arbel * Deprecate 'Get endpoint details - Generic' Playbook (#31196) * Deprecate 'Get endpoint details - Generic' Playbook * RN * Bump pack from version CommonPlaybooks to 2.4.36. * Bump pack from version CommonPlaybooks to 2.4.37. --------- Co-authored-by: Content Bot * Replacing the deprecated sub-playbook within the 'NGFW Internal Scan'… (#31197) * Replacing the deprecated sub-playbook within the 'NGFW Internal Scan' XSIAM playbook * RN * [Marketplace Contribution] CISO Metrics (#30641) (#31213) * "pack contribution initial commit" * Update pack_metadata.json * Update and rename dashboard-98f353a2-312b-49f2-8e58-d71f60daf3a7-CISO_Metrics.json to dashboard-98f353a2-312b-49f2-8e58-d71f60daf3a7-CommunityCommonDashboards.json Rename to CommunityCommonDashboards * Update pack_metadata.json Renamed "name": "CommunityCommonDashboards" * Update README.md Added description * Update README.md * Update and rename README.md to README.md * Rename dashboard-98f353a2-312b-49f2-8e58-d71f60daf3a7-CommunityCommonDashboards.json to dashboard-98f353a2-312b-49f2-8e58-d71f60daf3a7-CommunityCommonDashboards.json * Rename .pack-ignore to .pack-ignore * Rename .secrets-ignore to .secrets-ignore * Rename pack_metadata.json to pack_metadata.json * Update .pack-ignore * Update pack_metadata.json * Update .pack-ignore * Update and rename dashboard-98f353a2-312b-49f2-8e58-d71f60daf3a7-CommunityCommonDashboards.json to CISOMetrics.json Renamed to CISOMetrics * Update pack_metadata.json * Update pack_metadata.json * Update README.md --------- Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: Sapir Shuker <49246861+sapirshuker@users.noreply.github.com> Co-authored-by: David Uhrlaub <90627446+rurhrlaub@users.noreply.github.com> * Cybereason xsoar v 2.1.14 (#30647) (#31225) * added v2.1.14 codebase * fix pr comments * replace dummy md5 placeholder * Update Packs/Cybereason/Integrations/Cybereason/Cybereason.py * updated docker image python version * updated release notes docker version * added pagination params * updated docker image * fix lint errors * fix demisto validate errors * updated release notes * updated release notes * updated release notes * updated command name as per PR comment * removed manual filtering for response * updated function name to match the command name format * updated unit test as per new command name * added machinename filter to api query * moved empty output message to the top * updated docker image tag to latest * undo changes from unisolate endpoint playbook --------- Co-authored-by: suraj-metron <87964764+suraj-metron@users.noreply.github.com> Co-authored-by: Sapir Shuker <49246861+sapirshuker@users.noreply.github.com> * fixed polling support (#30873) * fixed polling support * fixed rn * added rn * added rn * XSUP-30786/Fix (#31168) * Added failing UT * Fixed the issue * Updated docker image * Updated RN * Update Packs/PAN-OS/ReleaseNotes/2_1_15.md Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> * Updated the bug fix and the UT * updated docker image --------- Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> * rewrite to js FirstArrayElement and LastArrayElement (#31228) * rewrite to js * added tpb * added empty test case to tpb * precommit fixes * change fromversion so build wont fail * Enable Core REST API with general XSIAM endpoints (#31226) * mostly works * added release notes * fixes from review * F5 APM fixed the marketplace build failure (#31236) * F5 APM Remove XSIAM tags * fix marketplace error * Add incidents field (#30393) (#31233) * add rawJSON field to incidents * release notes * update docker image tag * nit * fetching incident details * mapper + incident fields * remove incorrect incident field files * new incident field files, new mapper * sdk validate command changes * update release noteS * validation errors * fix validation errors * undo release notes changes * undo release notes change * undo release notes * undo release notes * undo release notes * nit * new release notes * remove playbook id * update docker image tag * revert release notes * revert RN * nit- remove filters used for testing * add details field to threats * remove try/except blocks * changing version * Update Abnormal_Security_Custom_Incident_types.json change from version * nit - remove changes used for demo * updating docker image * update docker image tag --------- Co-authored-by: William Olyslager Co-authored-by: sapirshuker Co-authored-by: Sapir Shuker <49246861+sapirshuker@users.noreply.github.com> * Update Docker Image To demisto/python3 (#31242) * Updated Metadata Of Pack CIRCL * Added release notes to pack CIRCL * Packs/CIRCL/Integrations/CirclCVESearch/CirclCVESearch.yml Docker image update * Updated Metadata Of Pack ipinfo * Added release notes to pack ipinfo * Packs/ipinfo/Integrations/ipinfo_v2/ipinfo_v2.yml Docker image update * Updated Metadata Of Pack AutoFocus * Added release notes to pack AutoFocus * Packs/AutoFocus/Integrations/FeedAutofocus/FeedAutofocus.yml Docker image update * Packs/AutoFocus/Integrations/AutofocusV2/AutofocusV2.yml Docker image update * Updated Metadata Of Pack MailSenderNew * Added release notes to pack MailSenderNew * Packs/MailSenderNew/Integrations/MailSenderNew/MailSenderNew.yml Docker image update * avoid to update Docker for AutoFocusv2 --------- Co-authored-by: israelpolishook * Fixes For 'IP Enrichment - Generic v2' Playbook (#31183) * Fixes For 'IP Enrichment - Generic v2' Playbook * RN * RN * Updated the 'InternalRange' playbook input's default value. * configured the 'extended_data' and 'threat_model_association' sub-playbook inputs * Bump pack from version CommonPlaybooks to 2.4.36. * Bump pack from version CommonPlaybooks to 2.4.37. * changed the default value of the 'ResolveIP' playbook input * re-added RN after merging from master * Fixes RN --------- Co-authored-by: Content Bot * Check if should run Instance role (#31245) * Added the sync from the saas bucket and modified the verify script to take the revision from the correct bucket. (#31254) * AWS Organizations (#30525) * init * commands template * aws-org-children-list * more commands * even more commands * added account commands * removed enhancement commands * use json_transform * unit-tests init * unit-tests continued * unit-tests continued some more * TPB * one more unit-test * one more unit-test * one more unit-test * name change * TPB * docs complete * pack readme * pack readme part 2 * readme modified * more tests * more tests * use get() * adde description * removed isFetch * added image * name change * CR changes * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update docker * put the commands back in * code complete * yml part 2 * yml part 3 * test template * unit-tests continued some more * unit-tests almost complete * unit-tests complete * fixed a few bugs * fixed unit-tests * added readme * update readme * added missing descriptions to readme * TPB * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * CR changes * demo changes * update docker * build wars: round 1 * build wars: round 2 * build wars: round 3; add unit-tests * build wars: round 4 * build wars: round 5 * build wars: round 6 --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * NextToken in CommandResults (#30501) * init * new design * added error in case of non nested input * RN * a tad more docs * Bump pack from version Base to 1.32.47. * Bump pack from version Base to 1.32.48. * Bump pack from version Base to 1.32.49. * improved doc-string * resolve conflicts * resolve conflicts * Bump pack from version Base to 1.32.52. --------- Co-authored-by: Content Bot * demisto-sdk-release 1.24.0 (#31268) * poetry files * update validate manager imports (#31179) * update validate manager imports * revert * Update Tests/configure_and_test_integration_instances.py * Edit file types test (#31170) * edited tests * s * s * edit --------- Co-authored-by: Content Bot Co-authored-by: Yuval Hayun <70104171+YuvHayun@users.noreply.github.com> Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> Co-authored-by: JudithB <132264628+jbabazadeh@users.noreply.github.com> * modified modeling rules of clearswift dlp (#31247) * modified modeling rules of clearswift dlp * modified the parsing rule of clearswiftdlp * Added release notes. * added dlp to pack ignore * added Clearswift to pack ignore * QRadar: continue to poll in case of networking issues (#31084) * Generalize the mode option in pre-commit (#30663) * args updated to match the update in the sdk * add merge-coverage-report and coverage-analyze * updaing pyproject.toml * poetry lock * restoring pyproject.toml and poetry.lock * pre-commit.yml * updates * test comment * use sdk ref * if * add github output * revert ilan changes * merge-pytest-reports --------- Co-authored-by: ilan * EXPANDR-1576 CortexXpanse Remediation Guidance changes (#31190) * EXPANDR-1576 CortexXpanse Remediation Guidance changes (#30712) * CortexXpanse RG changes * Fix flake8 errors * Fix unit test cases * Update docker version * update command name * Readme updates * docker update * Ignore BC error * fix packignore * Update release notes * update breaking change notes * update breaking change notes * correct RN --------- Co-authored-by: Chait A <112722030+capanw@users.noreply.github.com> Co-authored-by: ilappe * Feature/cyberint enhancement (#31252) * Feature/cyberint enhancement (#30493) * Update Docker Image To demisto/py3-tools (#25523) * Updated Metadata Of Pack FeedAWS * Added release notes to pack FeedAWS * Packs/FeedAWS/Integrations/FeedAWS/FeedAWS.yml Docker image update * update Cyberint Pack * update release note and incidentfields * update CommonType release note * update CommonType relesenotes * update CommonType relese notes * update CyberInt Related entity name * update release notes * add new incident field: Alert Data * foramt alert_data * update CyberInt Related Entity name to avoid validation errors * reset the CyberInt Related Entity name * update incident field name * Update 3_3_93.md * pre commit update docker * added known words * fixed the RN * known words --------- Co-authored-by: TalGumi <101499620+TalGumi@users.noreply.github.com> Co-authored-by: omerKarkKatz <95565843+omerKarkKatz@users.noreply.github.com> Co-authored-by: okarkkatz * [xsoar-8 coverage] - use poll functions from SDK clients (#31144) * update poetry * use poll functions * test against builds * try to fix ssl issue * timeout = 300 + verify ssl * fix ssl issues * fix incident pull * fix * make verify=false by default * fix ports bug * use sdk master * revert poetry * revert infra used for testing * [CrowdStrike Falcon Intel v2] Fixed an issue in 'cs-actors' and 'cs-reports' commands (#31265) * Fix the 'NoneType' object is not iterable issue * ruff * Update the docker image; Add RN * Update Packs/CrowdStrikeIntel/ReleaseNotes/2_0_34.md Co-authored-by: Dean Arbel --------- Co-authored-by: Dean Arbel * oncall- installation orders (#31253) * test * test * revert debugs * pre-commit --------- Co-authored-by: Jas Beilin * Core rest api docs fix (#31262) * Improved descriptions. * Added docs * Added rn. * Changed i.e to e.g * bugfix/XSUP-30713/port-scan-pb-issue-incident-failure (#31154) * Fix playbook input's default value, change to not required, add check for value not empty * Update playbook image * Update release notes * Bump pack from version CortexXDR to 6.0.5. * Moved InternalIPRanges input check to better location * Fix review comments --------- Co-authored-by: Content Bot * [PagerDuty v2] Added Support For Pagination (#30959) * commit init - lint and type annotation * typing * pagination function and some typing * fix api limit and pagination * added UT and test_data * added RN and description for args * generate readme * update docker * added UT * fix flake8 * more docstring, one more UT, fix send unnecessary parameters * fix f-string * fix pep8 * revert copy * fix parameters name * docs review * update docker * [ASM] EXPANDR 7225 - Update Ev1 Integration Display Name (#31234) (#31276) * Update Display Name * Update release notes * Update docker image and add period to descriptions Co-authored-by: John <40349459+BigEasyJ@users.noreply.github.com> Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> * Update Docker Image To demisto/python3 (#31286) * Updated Metadata Of Pack QualysFIM * Added release notes to pack QualysFIM * Packs/QualysFIM/Integrations/QualysFIM/QualysFIM.yml Docker image update * Updated Metadata Of Pack FortiSIEM * Added release notes to pack FortiSIEM * Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.yml Docker image update * Updated Metadata Of Pack FreshworksFreshservice * Added release notes to pack FreshworksFreshservice * Packs/FreshworksFreshservice/Integrations/FreshworksFreshservice/FreshworksFreshservice.yml Docker image update * Updated Metadata Of Pack KnowBe4_KMSAT * Added release notes to pack KnowBe4_KMSAT * Packs/KnowBe4_KMSAT/Integrations/KnowBe4KMSATEventCollector/KnowBe4KMSATEventCollector.yml Docker image update * Packs/KnowBe4_KMSAT/Integrations/KnowBe4KMSAT/KnowBe4KMSAT.yml Docker image update * Updated Metadata Of Pack SafeNet_Trusted_Access * Added release notes to pack SafeNet_Trusted_Access * Packs/SafeNet_Trusted_Access/Integrations/SafeNetTrustedAccessEventCollector/SafeNetTrustedAccessEventCollector.yml Docker image update * Updated Metadata Of Pack DelineaSS * Added release notes to pack DelineaSS * Packs/DelineaSS/Integrations/DelineaSS/DelineaSS.yml Docker image update * Updated Metadata Of Pack Cryptocurrency * Added release notes to pack Cryptocurrency * Packs/Cryptocurrency/Integrations/Cryptocurrency/Cryptocurrency.yml Docker image update * Updated Metadata Of Pack PANOSPolicyOptimizer * Added release notes to pack PANOSPolicyOptimizer * Packs/PANOSPolicyOptimizer/Integrations/PANOSPolicyOptimizer/PANOSPolicyOptimizer.yml Docker image update * Updated Metadata Of Pack DeveloperTools * Added release notes to pack DeveloperTools * Packs/DeveloperTools/Integrations/CreateIncidents/CreateIncidents.yml Docker image update * Add XSOAR_SAAS section to EDL description (#31264) * add XSOAR_SAAS section to EDL description * update RN * [XSUP 30575] Added full fields query param (#31272) * get indicators full fields data * pre-commit * release notes * tests and CR fixes * Update Packs/FeedCrowdstrikeFalconIntel/ReleaseNotes/2_1_13.md Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> --------- Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> * Update Docker Image To demisto/boto3py3 (#31287) * Updated Metadata Of Pack SecurityIntelligenceServicesFeed * Added release notes to pack SecurityIntelligenceServicesFeed * Packs/SecurityIntelligenceServicesFeed/Integrations/SecurityIntelligenceServicesFeed/SecurityIntelligenceServicesFeed.yml Docker image update * Updated Metadata Of Pack AWS-IAM * Added release notes to pack AWS-IAM * Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml Docker image update * Updated Metadata Of Pack AWS-Route53 * Added release notes to pack AWS-Route53 * Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml Docker image update * Updated Metadata Of Pack AWS-AccessAnalyzer * Added release notes to pack AWS-AccessAnalyzer * Packs/AWS-AccessAnalyzer/Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml Docker image update * Updated Metadata Of Pack AWS-GuardDuty * Added release notes to pack AWS-GuardDuty * Packs/AWS-GuardDuty/Integrations/AWSGuardDutyEventCollector/AWSGuardDutyEventCollector.yml Docker image update * Packs/AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml Docker image update * Updated Metadata Of Pack AWS-SecurityHub * Added release notes to pack AWS-SecurityHub * Packs/AWS-SecurityHub/Integrations/AWSSecurityHubEventCollector/AWSSecurityHubEventCollector.yml Docker image update * Updated Metadata Of Pack Aws-SecretsManager * Added release notes to pack Aws-SecretsManager * Packs/Aws-SecretsManager/Integrations/AwsSecretsManager/AwsSecretsManager.yml Docker image update * Update Docker Image To demisto/accessdata (#31288) * Updated Metadata Of Pack Exterro * Added release notes to pack Exterro * Packs/Exterro/Integrations/Exterro/Exterro.yml Docker image update * Update Docker Image To demisto/oci (#31290) * Updated Metadata Of Pack OracleCloudInfrastructure * Added release notes to pack OracleCloudInfrastructure * Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml Docker image update * Update Docker Image To demisto/py3-tools (#31289) * Updated Metadata Of Pack Intezer * Added release notes to pack Intezer * Packs/Intezer/Integrations/IntezerV2/IntezerV2.yml Docker image update * Updated Metadata Of Pack Zabbix * Added release notes to pack Zabbix * Packs/Zabbix/Integrations/Zabbix/Zabbix.yml Docker image update * Updated Metadata Of Pack FeedMalwareBazaar * Added release notes to pack FeedMalwareBazaar * Packs/FeedMalwareBazaar/Integrations/MalwareBazaarFeed/MalwareBazaarFeed.yml Docker image update * Updated Metadata Of Pack FeedGCPWhitelist * Added release notes to pack FeedGCPWhitelist * Packs/FeedGCPWhitelist/Integrations/FeedGoogleIPRanges/FeedGoogleIPRanges.yml Docker image update * Updated Metadata Of Pack AccentureCTI_Feed * Added release notes to pack AccentureCTI_Feed * Packs/AccentureCTI_Feed/Integrations/ACTIIndicatorFeed/ACTIIndicatorFeed.yml Docker image update * Updated Metadata Of Pack SEKOIAIntelligenceCenter * Added release notes to pack SEKOIAIntelligenceCenter * Packs/SEKOIAIntelligenceCenter/Integrations/SEKOIAIntelligenceCenter/SEKOIAIntelligenceCenter.yml Docker image update * Updated Metadata Of Pack JARM * Added release notes to pack JARM * Packs/JARM/Integrations/JARM/JARM.yml Docker image update * Updated Metadata Of Pack Anomali_ThreatStream * Added release notes to pack Anomali_ThreatStream * Packs/Anomali_ThreatStream/Integrations/AnomaliThreatStreamv3/AnomaliThreatStreamv3.yml Docker image update * Updated Metadata Of Pack CommonWidgets * Added release notes to pack CommonWidgets * Packs/CommonWidgets/Scripts/RSSWidget/RSSWidget.yml Docker image update * Updated Metadata Of Pack FiltersAndTransformers * Added release notes to pack FiltersAndTransformers * Packs/FiltersAndTransformers/Scripts/Jmespath/Jmespath.yml Docker image update * Update Docker Image To demisto/armorblox (#31291) * Updated Metadata Of Pack Armorblox * Added release notes to pack Armorblox * Packs/Armorblox/Integrations/Armorblox/Armorblox.yml Docker image update * Update Docker Image To demisto/crypto (#31292) * Updated Metadata Of Pack AzureKeyVault * Added release notes to pack AzureKeyVault * Packs/AzureKeyVault/Integrations/AzureKeyVault/AzureKeyVault.yml Docker image update * Updated Metadata Of Pack AzureSentinel * Added release notes to pack AzureSentinel * Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel.yml Docker image update * Updated Metadata Of Pack AzureDevOps * Added release notes to pack AzureDevOps * Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps.yml Docker image update * Updated Metadata Of Pack MicrosoftCloudAppSecurity * Added release notes to pack MicrosoftCloudAppSecurity * Packs/MicrosoftCloudAppSecurity/Integrations/MicrosoftCloudAppSecurity/MicrosoftCloudAppSecurity.yml Docker image update * Updated Metadata Of Pack AzureRiskyUsers * Added release notes to pack AzureRiskyUsers * Packs/AzureRiskyUsers/Integrations/AzureRiskyUsers/AzureRiskyUsers.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphGroups * Added release notes to pack MicrosoftGraphGroups * Packs/MicrosoftGraphGroups/Integrations/MicrosoftGraphGroups/MicrosoftGraphGroups.yml Docker image update * Updated Metadata Of Pack AzureSQLManagement * Added release notes to pack AzureSQLManagement * Packs/AzureSQLManagement/Integrations/AzureSQLManagement/AzureSQLManagement.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphAPI * Added release notes to pack MicrosoftGraphAPI * Packs/MicrosoftGraphAPI/Integrations/MicrosoftGraphAPI/MicrosoftGraphAPI.yml Docker image update * Updated Metadata Of Pack MicrosoftTeams * Added release notes to pack MicrosoftTeams * Packs/MicrosoftTeams/Integrations/MicrosoftTeamsManagement/MicrosoftTeamsManagement.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphApplications * Added release notes to pack MicrosoftGraphApplications * Packs/MicrosoftGraphApplications/Integrations/MicrosoftGraphApplications/MicrosoftGraphApplications.yml Docker image update * Update Docker Image To demisto/sixgill (#31293) * Updated Metadata Of Pack Cybersixgill-ActionableAlerts * Added release notes to pack Cybersixgill-ActionableAlerts * Packs/Cybersixgill-ActionableAlerts/Integrations/CybersixgillActionableAlerts/CybersixgillActionableAlerts.yml Docker image update * Updated Metadata Of Pack Sixgill-Darkfeed * Added release notes to pack Sixgill-Darkfeed * Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed_Enrichment/Sixgill_Darkfeed_Enrichment.yml Docker image update * Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed/Sixgill_Darkfeed.yml Docker image update * Update Docker Image To demisto/carbon-black-cloud (#31295) * Updated Metadata Of Pack CarbonBlackDefense * Added release notes to pack CarbonBlackDefense * Packs/CarbonBlackDefense/Integrations/CarbonBlackLiveResponseCloud/CarbonBlackLiveResponseCloud.yml Docker image update * Update Docker Image To demisto/taxii2 (#31294) * Updated Metadata Of Pack FeedDHS * Added release notes to pack FeedDHS * Packs/FeedDHS/Integrations/DHSFeedV2/DHSFeedV2.yml Docker image update * Updated Metadata Of Pack FeedUnit42v2 * Added release notes to pack FeedUnit42v2 * Packs/FeedUnit42v2/Integrations/FeedUnit42v2/FeedUnit42v2.yml Docker image update * MS IIS Update2 (#31256) * Updated MicrosoftIISWebServerModelingRules_1_3 * Updated ModelingRules filters * Updated ModelingRules filters * Updated ReleaseNotes * Upated ReleaseNotes * CrowdStrikeFalconX-genreic-polling (#31189) * old playbooks deprecated and new one added * readme file edited * set the interval from the inputs * fixes for release notes * added extensions to known words * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_File_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_File_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_File_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_URL_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_File_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_File_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_File_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/ReleaseNotes/1_2_37.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/ReleaseNotes/1_2_37.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/ReleaseNotes/1_2_37.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/ReleaseNotes/1_2_37.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_File_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_File_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_File_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * minor fixes for description * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_URL_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_URL_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CrowdStrikeFalconX/Playbooks/Detonate_URL_-_CrowdStrike_Falcon_Intelligence_Sandbox_v2.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Add Symantec MSS to ignored items (#31296) * [XSUP 30870] Added full fields option for cs-actors and cs-reports commands (#31271) * Added the display_full_fields argument * pre-commit * release notes * tests and CR fixes * resolve conflict * pre-commit * CR fixes * docker * pre-commit * add myself as codeowner (#31314) * ORKL Feed Integration 1.0.0 Initial Release (#31166) * ORKL Feed Integration 1.0.0 Initial Release (#31101) Co-authored-by: Martin Ohl * [VirusTotal] Add suspicious threshold (#31220) * [VirusTotal] Add suspicious threshold (#31021) * fixing CimTrak_test.py unit tests (#31308) fixing CimTrak_test.py unit tests #31308 * Add new command and bug fix. (#31311) * Anomali ThreatStream v3 - Fix threatstream-get-indicators command (#31269) * fix get_indicators method * update RN * update docker * update test * update test * update get_indicators method * update RN * Update Packs/Anomali_ThreatStream/ReleaseNotes/2_2_9.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * update docker * update docker --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * SentinelOne v2: Add 2 new commands (#31312) * fixing jira file attachments (#31297) fixing jira file attachments, fixing mapping of newly created tickets #31297 * CiscoSMA Update (#31315) * Updated ModelingRules * Updated ReleaseNotes * Updated ReleaseNotes * updated docs (#31192) * updated docs * running pre-commit and docker * docker update * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * remove package-lock file * cr note * Update Packs/MicrosoftGraphDeviceManagement/ReleaseNotes/1_1_20.md Co-authored-by: EyalPintzov <91007713+eyalpalo@users.noreply.github.com> --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> Co-authored-by: EyalPintzov <91007713+eyalpalo@users.noreply.github.com> * Fix an issue when there is only one incident in fetch_incidents powershell (#31267) * added -AsArray * updated the docker image and added . * RN * unit tests and docker image * rn * docker image and release notes * Update Packs/Base/ReleaseNotes/1_32_53.md Co-authored-by: EyalPintzov <91007713+eyalpalo@users.noreply.github.com> * updated the unit tests --------- Co-authored-by: EyalPintzov <91007713+eyalpalo@users.noreply.github.com> * Get Entity Alerts by MITRE Tactics - Performance Improvements (Refactor) (#31232) * Added playbooks * New playbooks images, formatted playbooks, and added RN * Updated pb image to be in light mode * Further improvements to playbooks, updated docs, and updated playbook images * Bump pack from version CortexXDR to 6.0.6. * Changed alert to incident to fix validation * Descriptions --------- Co-authored-by: Content Bot * fix for sdk nightly e2e tests (#31310) * [qradar-v3] - handle connection errors (#31246) * [qradar-v3] - handle connection errors * add uts * bump rn * remove irrelevant imports * update code * timeout = 300 * bump rn * update implementation * docker image * fixes * remove imports * rn * update debug-message * update log * fix docker-image * fix ut * oncall-sdk-nightly-create-xsoar-instance (#31300) * overwrite the filter env file * remove space * remove print * Update .gitlab/ci/.gitlab-ci.on-push.yml Co-authored-by: Koby Meir --------- Co-authored-by: Koby Meir * [ASM] - EXPANDER 7238 - Jira Playbook Support for V2 and V3 Project Key (#31273) (#31322) * Add support V2 and V3, remove default project key - Add data collection task for customer - Leave Jira Project Key input as blank - Add support for project key passed into Jira V2 and V3 integrations * Add release notes * Update Playbook ReadMe * Add task description * Update release notes Co-authored-by: John <40349459+BigEasyJ@users.noreply.github.com> Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> * Support contributions when the name of the repo isn't content (#31320) * update handle_external_pr.py * set repo_name arg as optional * Oncall sdk nightly create xsoar instance (#31324) Oncall sdk nightly create xsoar instance #31324 * CIAC-4556/xdr-remote-psexec-lolbin-command-execution-playbook (#29092) * Add playbook and readme files * Add updated files * Add playbook image * Update release notes * Fix validation error * Bump pack from version CortexXDR to 5.1.0. * Bump pack from version CortexXDR to 5.2.0. * Bump pack from version CortexXDR to 5.2.0. * Bump pack from version CortexXDR to 5.2.0. * Add CommandLine verdict to layout * Update according to demo review comments * Bump pack from version CortexXDR to 5.2.0. * Bump pack from version CortexXDR to 5.2.0. * Add field for cmd line verdict * Update layout * Fix review comments * Update from master * Update Packs/CortexXDR/ReleaseNotes/5_2_0.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/ReleaseNotes/5_2_0.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Remote_PsExec_with_LOLBIN_command_execution_alert_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Fix review comments and validations * Apply suggestions from code review Fix docs review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Remote_PsExec_with_LOLBIN_command_execution_alert.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Remote_PsExec_with_LOLBIN_command_execution_alert.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Remote_PsExec_with_LOLBIN_command_execution_alert.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Remote_PsExec_with_LOLBIN_command_execution_alert.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Remote_PsExec_with_LOLBIN_command_execution_alert.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Remote_PsExec_with_LOLBIN_command_execution_alert.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Remote_PsExec_with_LOLBIN_command_execution_alert.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Fix review comments * Remove duplicate task for alert details, update playbook image * Fix skipifunavailable validations and update release notes * Fix review comments * Update release notes * Update release notes * Bump pack from version CortexXDR to 5.2.0. * Fix review comments * Update release notes * Bump pack from version CortexXDR to 5.2.2. * Bump pack from version CortexXDR to 5.2.3. * Fix review comments * Fix validation error * Fix validation errors * Update release notes * Fix conflicts * removed already added incident field * Update release notes * Fix validation errors * Fix validation errors * revert file changes * Fix validation errors * Fix validation errors * Bump pack from version CortexXDR to 6.0.4. * Fix review comments * Fix review comments * Update to correct playbook image * Bump pack from version CortexXDR to 6.0.5. * Update 6_0_5.md * Update release notes * Update 6_0_5.md * Bump pack from version CortexXDR to 6.0.7. * Fix precommit errors --------- Co-authored-by: Content Bot Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update README.md (#31299) * Last Mirrored New Field & Qradar fix (#31251) * add field * Bump pack from version CommonTypes to 3.3.95. * fix * review fix --------- Co-authored-by: Content Bot * Update native candidate to py3-native:8.4.0.82817 (#31319) * SplunkPy missing incidents (#30783) * Used exclusion of even ids * Reverted changes in unit tests * Fixed unbound issue * Added last fetched notables * Added potential solution * Comments in UTs * Added UTs * Added UTs with explanation * Added RNs * Fixed UTs and updated how we exclude ids * Fixed conflicts * Fixed CR * Fixed conflicts * Updated docker image * Fixed pre-commit in test file * Removed second pytest * Fixed comments in test file * MATI - Supporting multiple inputs for generic enrichment commands (#30940) (#31334) * Supporting multiple inputs for generic enrichment commands * Return list of CommandResults * Re-adding rawJSON * Bumping docker version * Relesase Notes * Tests * Tests * Adding details to contexts * Fixing tests * Bumping docker * Bumping docker * Fixing spacing * Fixing spacing * Fixing fetch --------- Co-authored-by: Christopher Hultin Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> * [Cortex Data Lake] Update the Docker Image (#31337) * Support Threat Assessment functionality in MS Graph Security (#30110) * added yml and the first command in code * added commands * added to description in yml * added readme for first command * added readme to second command * added third command to readme * added url command to readme * added list command to readme * added tests files * minor edits * added unittests * added unittest * updated docker image * added rn * edited readme * edit * fixed lint errors * fixed validation errors * fixed rn * edits precommits errors * fixed unittest for test auth code * edited tpb * added unittests * to revert some of these changes * update after doc review * added unittests * removed checking server version in CSP * updated docker image * added rn * Bump pack from version Base to 1.32.41. * reverted changes for csp * reveeted changes * deleted rn * added fromversion field * added unittest * updated for pre commit * updated for pre commit * edits after build failed * removed file * edits * added the tpb * fixed tpb * edited the list command * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_5.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * updated docker image * edited after build failed * reverted changes * updated do * added arg * added rn * updated docker image * edit * edits after cr * updated do * edited the get user call * checked the 2 other commands * edited yml * updated do * edited test * removed comments * updated do * edit * edit --------- Co-authored-by: Content Bot Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * incident field helloworld onprem (#31340) * update ParseEmailFilesV2 to 0.1.19 (#31331) * update Docker image and added bcc * update rn * update tests * Update Packs/CommonScripts/ReleaseNotes/1_12_55.md Co-authored-by: Shahaf Ben Yakir <44666568+ShahafBenYakir@users.noreply.github.com> --------- Co-authored-by: Shahaf Ben Yakir <44666568+ShahafBenYakir@users.noreply.github.com> * update readme (#31343) * [CommonServer.js] Update emailRegex (#31148) change email regex * Ciac 3790/add auto determine LDAP vendor (#31124) * Added auto determine LDAP vendor * Added test and RN * fix lint and rn * added to readme * docker * changed default vendor param to auto * [Versa Director] Update response data formats (#31327) * Remove accept: application/xml from get requests * Remove redundant get() from request responses * Update UTs * Release notes; pre-commit updates * Update UTs; Revert relevant get() functions * Revert relevant get() functions * Fix syntax error * Update Packs/VersaDirector/ReleaseNotes/1_0_7.md Co-authored-by: Jasmine Beilin <71636766+JasBeilin@users.noreply.github.com> * Update 1_0_7.md --------- Co-authored-by: Jasmine Beilin <71636766+JasBeilin@users.noreply.github.com> * Replace LastMirroredInTime incident field with Last Mirrored Time Stamp incident field in QRadar (#31281) * add field * Last Mirrored Time Stamp * fix unrelated release notes * RN * docker image and release notes * rn * rn * docker image and release notes * RN * updates * update * unit tests for the script * update rn and bc * docstring for the ubit tests --------- Co-authored-by: arikday Co-authored-by: ArikDay <115150768+ArikDay@users.noreply.github.com> * Tessian integration setup (#31350) * Tessian integration setup (#31028) * revert package-lock.json --------- Co-authored-by: NicBunn-PlutoFlume <112942358+NicBunn-PlutoFlume@users.noreply.github.com> Co-authored-by: adi88d Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * Kiteworks Modeling CIAC-6377 (#31230) * init-pack * parsing-rules * json-format-modeling * README.md * modeling-rules * refactor-modeling-rules * fix-modeling-rules-issues * single-line-format-modeling * activity-group-type-modeling * refactor-modeling-rules * refactor-modeling-rules * Update Packs/Kiteworks/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * refactor-modeling-rules * refactor-modeling-rules * modeling-rules-json-fix * modeling-rules-json-refactor * modeling-rules-remove-unused-field --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Prisma SASE - Quarantine Host With Active Threat (#31346) * New playbook for Prisma SASE * update RN * update RN * update playbook description * update playbook readme * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * update RN * update playbook readme * update RN --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Symantec web security service pack long running (#30990) * first commit * commit * commit * first commit * update pack_metadata file * extract_logs_from_response changes * get_events_command changes * commit * commit * add logs * commit * commit * commit * commit * commit * commit * commit * commit * commit * commit * commit * commit * commit * Fixed the memory load on Docker * commit * first commit for rewrite * commit * commit * add UT and finish implementation * design * Change pack name * add-modeling-rules * add-parsing-rules * siem-content-minor-fixes * add UT and docstring * add-siem-documentation * update-siem-documentation * update-siem-documentation * commit * Change readme file * fix UT and add description to pack_metadata * commit * fix mypy flake8 * add UT * refactor-siem-content * Apply suggestions from code review Comment corrections Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * comment corrections * comment corrections and add UT for it * comment correction * mypy * update Docker * comment corrections * comment corrections * update docker * fix UT and pre-commit * commit * commit * fix pre commit * commit --------- Co-authored-by: Chanan Welt Co-authored-by: cweltPA <129675344+cweltPA@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * FireEye ETP Event Collector fixes (#30819) * Fixed date parsing * format and tests * fixed date parsing from and to the api * fixed tests * fixed invalid date order * fetch in asc order * fetch in asc order * fix unitesing * fix potential formatting issue * change first_run * change first_run * Fix RN * Fix lint * Fix lint * added unitests * added unitests * CR fixes * CR fixes * Update Docker Image To demisto/accessdata (#31373) * Updated Metadata Of Pack Exterro * Added release notes to pack Exterro * Packs/Exterro/Integrations/Exterro/Exterro.yml Docker image update * Update Docker Image To demisto/boto3py3 (#31372) * Updated Metadata Of Pack SecurityIntelligenceServicesFeed * Added release notes to pack SecurityIntelligenceServicesFeed * Packs/SecurityIntelligenceServicesFeed/Integrations/SecurityIntelligenceServicesFeed/SecurityIntelligenceServicesFeed.yml Docker image update * Updated Metadata Of Pack AWS-IAM * Added release notes to pack AWS-IAM * Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml Docker image update * Updated Metadata Of Pack AWS-Route53 * Added release notes to pack AWS-Route53 * Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml Docker image update * Updated Metadata Of Pack AWS-AccessAnalyzer * Added release notes to pack AWS-AccessAnalyzer * Packs/AWS-AccessAnalyzer/Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml Docker image update * Updated Metadata Of Pack AWS-GuardDuty * Added release notes to pack AWS-GuardDuty * Packs/AWS-GuardDuty/Integrations/AWSGuardDutyEventCollector/AWSGuardDutyEventCollector.yml Docker image update * Packs/AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml Docker image update * Updated Metadata Of Pack AWS-SecurityHub * Added release notes to pack AWS-SecurityHub * Packs/AWS-SecurityHub/Integrations/AWSSecurityHubEventCollector/AWSSecurityHubEventCollector.yml Docker image update * Updated Metadata Of Pack Aws-SecretsManager * Added release notes to pack Aws-SecretsManager * Packs/Aws-SecretsManager/Integrations/AwsSecretsManager/AwsSecretsManager.yml Docker image update * [ASM] - EXPANDER 3741 - XSIAM Layout and Rule (#31352) * [ASM] - EXPANDER 3741 - XSIAM Layout and Rule (#31212) * Update Rem. Guidance Playbook, add new fields Created fields: - "ASM - Attack Surface Rule Category" - "ASM - Attack Surface Rule Description" - "ASM - Attack Surface Rule Priority" - "ASM - Attack Surface Rule Remediation Guidance" Set fields in Remediation Guidance playbook * Update release notes * Update field descriptions * Format JSON files * update unsearchable and fromVersion * Add ASM layout and rule * Add release notes * Update pack ReadMe * Update server content items * Add marketplace to layout * Update release notes version * Add AlertType to server content items * Add IncidentType to server content items * update ASM.json layout * remove ASM from server_content_items.json --------- Co-authored-by: John <40349459+BigEasyJ@users.noreply.github.com> Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> Co-authored-by: adi88d * Feed Recorded Future download all compressed data on disk bug (#30981) * Hint for solution * Potential solution * Tried solution, did not work * Added potential solution * Added RNs and updated docker image * Added debug logs * Resolved conflicts * Added handling of cut-off bytes while streaming * Added unit tests and test data * Outsourced decoder * Went over CR comments * Fixed Chunk Size * Added description to fixture * Ran pre-commit * Refactored decoding mechanism * Fix chunk size * Update FeedRecordedFuture.yml * Update 1_0_32.md * CISCO SMA u200b Update (#31349) * Updated ModelingRules * Updated ReleaseNotes * Updated ReleaseNotes * Updated ModelingRules logic * [e2e xsoar-saas] - fix issue with taxii2-server test (#31362) * Update Docker Image To demisto/crypto (#31368) * Updated Metadata Of Pack MicrosoftDefenderAdvancedThreatProtection * Added release notes to pack MicrosoftDefenderAdvancedThreatProtection * Packs/MicrosoftDefenderAdvancedThreatProtection/Integrations/MicrosoftDefenderAdvancedThreatProtection/MicrosoftDefenderAdvancedThreatProtection.yml Docker image update * Updated Metadata Of Pack AzureSecurityCenter * Added release notes to pack AzureSecurityCenter * Packs/AzureSecurityCenter/Integrations/AzureSecurityCenter_v2/AzureSecurityCenter_v2.yml Docker image update * Update Docker Image To demisto/armorblox (#31376) * Updated Metadata Of Pack Armorblox * Added release notes to pack Armorblox * Packs/Armorblox/Integrations/Armorblox/Armorblox.yml Docker image update * Update Docker Image To demisto/pymisp2 (#31369) * Updated Metadata Of Pack MISP * Added release notes to pack MISP * Packs/MISP/Integrations/MISPV3/MISPV3.yml Docker image update * Update Docker Image To demisto/genericsql (#31370) * Updated Metadata Of Pack GenericSQL * Added release notes to pack GenericSQL * Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml Docker image update * MS IIS Update3 (#31385) * Updated ModelingRules * Updated ReleaseNotes * Updated ReleaseNotes * Updated ModelingRules * Updated ModelingRules * Add a manual fatch once in 12 hours (#31123) * fixes * http module * CSV * common server * tests * RN * link * RN * change RN * one more * pre commit * update base version * [known_words] * removing typing * swap the known words * RN * fix RN * Bump pack from version FeedMalwareBazaar to 1.0.30. * Bump pack from version AccentureCTI_Feed to 1.1.27. * Bump pack from version FeedGCPWhitelist to 2.0.30. * Bump pack from version Base to 1.32.52. * make it better * docs * CR * cr * Fixing dirty merge #1 * fixing dirty merge #2 * fix dirty merge #3 * more * fox dirty merge #4 * common * poetry * fix dirty merge #5 * fix test date * base rn * RN * fix common docstring * fix rn * fix errors in build * shirley * Bump pack from version Base to 1.32.54. * RN * mypy * fix common server * ignore type error * skip test * fix test name * add import * remove the import, test is failing * fixed function and test * space * conf * add a test for a uniq time zone * fix test * move the import into the function * move the import from the test as well * replace timezone with pytz, to fit python 2 * Bump pack from version Base to 1.33.1. * fix test comment --------- Co-authored-by: Content Bot * Fix gmail get mail context output (#31342) * update context path * added RN * updated readme * update docker * added run get attachments argument * pre commit fixes * pre commit fixes * cr fixes * cr fixes * cr fixes * update RN * update docker * Updated README.md (#31347) (#31363) * [Zscaler] Add URLs to Retaining Parent Category (#30637) * add retaining parent url * Update retaining_parent_category_url argument * Add retaining-parent-category-ip to yml * Add retaining-parent-category-ip logic * ip argument no longer marked required * url argument no longer marked required * retaining_parent_category args are None by default * Add retaining-parent-category-url to remove-url * Add retaining-parent-category-ip to remove-ip * UT fix; ruff updates * Remove redundant context output * Update release notes * FIx Failed UTs * Case of only one ip argument in remove commands * pre-commit updates * Update release notes * Change display value to original value * Update release notes * UT Coverage * Add UTs; Remove redundant debug logs * Update release notes * Apply suggestions from code review Co-authored-by: Jasmine Beilin <71636766+JasBeilin@users.noreply.github.com> * Remove "pragma no cover" from unrelated UTs * Revert open function's default 'r' value for readability --------- Co-authored-by: Jasmine Beilin <71636766+JasBeilin@users.noreply.github.com> * Update Docker Image To demisto/python3 (#31371) * Updated Metadata Of Pack QualysFIM * Added release notes to pack QualysFIM * Packs/QualysFIM/Integrations/QualysFIM/QualysFIM.yml Docker image update * Updated Metadata Of Pack FortiSIEM * Added release notes to pack FortiSIEM * Packs/FortiSIEM/Integrations/FortiSIEMV2/FortiSIEMV2.yml Docker image update * Updated Metadata Of Pack FreshworksFreshservice * Added release notes to pack FreshworksFreshservice * Packs/FreshworksFreshservice/Integrations/FreshworksFreshservice/FreshworksFreshservice.yml Docker image update * Updated Metadata Of Pack KnowBe4_KMSAT * Added release notes to pack KnowBe4_KMSAT * Packs/KnowBe4_KMSAT/Integrations/KnowBe4KMSATEventCollector/KnowBe4KMSATEventCollector.yml Docker image update * Packs/KnowBe4_KMSAT/Integrations/KnowBe4KMSAT/KnowBe4KMSAT.yml Docker image update * Updated Metadata Of Pack SafeNet_Trusted_Access * Added release notes to pack SafeNet_Trusted_Access * Packs/SafeNet_Trusted_Access/Integrations/SafeNetTrustedAccessEventCollector/SafeNetTrustedAccessEventCollector.yml Docker image update * Updated Metadata Of Pack DelineaSS * Added release notes to pack DelineaSS * Packs/DelineaSS/Integrations/DelineaSS/DelineaSS.yml Docker image update * Updated Metadata Of Pack Cryptocurrency * Added release notes to pack Cryptocurrency * Packs/Cryptocurrency/Integrations/Cryptocurrency/Cryptocurrency.yml Docker image update * Updated Metadata Of Pack PANOSPolicyOptimizer * Added release notes to pack PANOSPolicyOptimizer * Packs/PANOSPolicyOptimizer/Integrations/PANOSPolicyOptimizer/PANOSPolicyOptimizer.yml Docker image update * Updated Metadata Of Pack DeveloperTools * Added release notes to pack DeveloperTools * Packs/DeveloperTools/Integrations/CreateIncidents/CreateIncidents.yml Docker image update * Updated Metadata Of Pack QualysFIM * Updated Metadata Of Pack QualysFIM * [Marketplace Contribution] MicrosoftGraphTeams - Content Pack Update (#31097) (#31387) * "contribution update to pack "MicrosoftGraphTeams"" * Update MicrosoftGraphTeams.py uncomment 'topic' to allow subject for group type chat. * Update MicrosoftGraphTeams.yml fixed validation error for descriptions. * Update Packs/MicrosoftGraphTeams/Integrations/MicrosoftGraphTeams/MicrosoftGraphTeams.py done * cr * Update 1_1_0.md * Update MicrosoftGraphTeams.yml * Update 1_1_0.md * Update 1_1_0.md * Update MicrosoftGraphTeams.yml --------- Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: Vipul Kaneriya <50216620+vipulkaneriya@users.noreply.github.com> Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> Co-authored-by: MLainer1 * Cybersixgill alerts typosquatting (#31386) * Cybersixgill alerts typosquatting (#30787) * Added mapper for 2 custom incident fields * Updated release notes. * Added typosquatting to known words * new Incident fields and incomming mapper formated * Release notes reviewed. * setting unseachable to true. * Suspicious and Triggered domain as tables. * Moved 3 mappings from code to mapper. * Updated test case * Updated test case * Added default mapper and updated docker image version * Added breaking change note * Removed breaking change note * Renamed files as per suggestion * renamed mapper as per suggestion * Added new release note. * Changed id and name for incident fields and updated docker image name * update RN * update RN, update fields names, update mapper * update id, update RN * Update 1_2_10.md * Update incidentfield-Cybersixgill_Triggered_Domain.json * update docker * ID value contained invalid caps character. * changing type in fields to tagselect --------- Co-authored-by: Sapir Shuker <49246861+sapirshuker@users.noreply.github.com> Co-authored-by: sapirshuker * docker image update --------- Co-authored-by: syed-loginsoft <97145640+syed-loginsoft@users.noreply.github.com> Co-authored-by: Sapir Shuker <49246861+sapirshuker@users.noreply.github.com> Co-authored-by: sapirshuker * Armis event collector extend alerts data set (#31378) * full working alert fetch flow. * Unify try catch Different RN phrasing * Adding unittest to test Alert event flow * bump docker version. * Adding doc string and log writes. * fixed - add-test-xdr-env-ng-nightly (#31155) * fixed * added nightly flow_type for NG * added xsoar_ng_server_ga to CONTENT_NIGHTLY_JOBS for jobs-done-check-nightly * added xsoar_ng_server_ga to CONTENT_NIGHTLY_JOBS for jobs-done-check-nightly * [EWS v2] Update docker image with previous exchangelib version (#31357) * Use "alert" instead of "incident" for XSIAM content (#31223) * DBotFindSimilarIncidents complete * FindSimilarIncidents complete * minor adjustments * fixed unit-tests * build wars: round 1 * update docker * added RN * fix unit-tests * CR changes * Bump pack from version Base to 1.32.53. * use get() on demistoVersion() * Bump pack from version Base to 1.32.54. * update docker * update docker * build wars: round 2 * Bump pack from version CommonScripts to 1.12.56. * Bump pack from version Base to 1.33.1. * Bump pack from version Base to 1.33.2. * update docker --------- Co-authored-by: Content Bot * [ExtractEmailTransformer] Convert to JS (#31159) * [transformers] Enhance to be more durable * Add RN * Add RN; run format * Bump pack from version CommonScripts to 1.12.43. * IsEmailAddressInternal set isArray to true * Add TPB for SetAndHandleEmpty * Add TPB for IsEmailAddressInternal * Bump pack from version CommonScripts to 1.12.44. * Add TPB for ExtractEmailTransformer * Update the TPB for SetIfEmpty * Update the TPB for SetIfEmpty * Compatibility with XSOAR 6.9.0 * Update Packs/FiltersAndTransformers/Scripts/WhereFieldEquals/WhereFieldEquals.js * Delete pytest files * Bump pack from version CommonScripts to 1.12.46. * Bump pack from version CommonScripts to 1.12.47. * Bump pack from version CommonScripts to 1.12.48. * Bump pack from version CommonScripts to 1.12.49. * Bump pack from version CommonScripts to 1.12.50. * First commit * Added RN * empty * Test to update emailRegex * Test to update emailRegex 1 * fix version * fix RN * Bump pack from version Base to 1.32.52. * Fix the regex * Add two versions: py and JS * Bump pack from version Base to 1.32.53. * Split by versions * Split by versions * Add ignore from BA109 * Fix the regex * Bump pack from version Base to 1.32.54. * Revert * Revert * Change the files name * Update the TPB * Fix the unit test * Update the README file * Add ignore; Update the docker image; Add RN * Update the docker image * Fix the conf.json * Add "pragma: no cover" to main * Update the TPB --------- Co-authored-by: Content Bot * Fix for playbooks that uses deprecated sub-playbooks (#31330) * The sub-playbook of wildfire detonate file was changed to v2 * Replaced the old version of Cortex XDR - Retrieve File with the new version * Crowdstrike detonate file was changed to a new version * release notes update * release notes update * readme files updated * release note * fix for taskid and task field * fixes for taskid and task not equal value * release notes fix * added new images for the playbooks * Unique value fix * RN updated * fixes for PR * RN fix * fix * fix * RN fix * Update Packs/CommonPlaybooks/ReleaseNotes/2_4_39.md Co-authored-by: Sasha Sokolovich <88268646+ssokolovich@users.noreply.github.com> * PN fix and unique fix * fix for error in the build * Update Packs/CommonPlaybooks/Playbooks/playbook-Detonate_URL_-_Generic_v1.5.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/Playbooks/playbook-Detonate_URL_-_Generic_v1.5.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/Playbooks/playbook-Detonate_URL_-_Generic_v1.5.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/Playbooks/playbook-Detonate_URL_-_Generic_v1.5.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/Playbooks/playbook-Detonate_URL_-_Generic_v1.5.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/Core/Playbooks/playbook-Ransomware_Enrich_and_Contain_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/Core/Playbooks/playbook-Ransomware_Enrich_and_Contain_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/Core/Playbooks/playbook-Ransomware_Enrich_and_Contain_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/Core/ReleaseNotes/3_0_3.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CortexXDR/ReleaseNotes/6_0_8.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/Playbooks/playbook-Detonate_URL_-_Generic_v1.5.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/ReleaseNotes/2_4_39.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/ReleaseNotes/2_4_39.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/Core/Playbooks/playbook-Ransomware_Enrich_and_Contain.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/Core/Playbooks/playbook-Ransomware_Enrich_and_Contain_README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --------- Co-authored-by: Sasha Sokolovich <88268646+ssokolovich@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * added the send_data_to_xsiam func (#29709) * added the send_data_to_xsiam func * changes * minor fixes * change * edit * added RN * added unittests * added rn * Bump pack from version Base to 1.32.47. * fixed import * Bump pack from version Base to 1.32.48. * Bump pack from version Base to 1.32.49. * fix headers names * added rn * updated unittest * added to demistomock * added rn * fix rn * edit * Bump pack from version Base to 1.32.54. * Bump pack from version Base to 1.33.1. * added rn * edits after cr * edit * edit * Bump pack from version Base to 1.33.3. * edits for cover analysis --------- Co-authored-by: Content Bot * EXPANDR-7181 Fix issues for AWS rule logic (#31401) * EXPANDR-7181 Fix issues for AWS rule logic (#31237) * Fix issues * update release notes * updated docker image * Update Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_9.md Co-authored-by: John <40349459+BigEasyJ@users.noreply.github.com> * scenario 4 and 5 changes * update test cases * Update Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_9.md Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> --------- Co-authored-by: John <40349459+BigEasyJ@users.noreply.github.com> Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * Update 1_1_9.md * Update 1_1_9.md * Update docker --------- Co-authored-by: Chait A <112722030+capanw@users.noreply.github.com> Co-authored-by: John <40349459+BigEasyJ@users.noreply.github.com> Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * RSA secureID CIAC-8811 (#31392) * New pack of RSA secureID * Update Packs/RSASecureID/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/RSASecureID/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/RSASecureID/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/RSASecureID/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * changes to the README file * small changes to the README * mismatch betweeb dataset names --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update "malware investigation and response" and cortex xdr image path (#31403) * updated path to image * Updated the pic for cortex xdr * [Qradar] - add timeout param, update test-module and implement retry for connection errors (#31339) * add qradar timeout param * add timeout to client * add docs and bump rn * fixes * refactor test-module * retry for http_request * fixes * elif * rn and docker image * rn * bump rn * update docker * logger * add fetch-interval and set default to 10 * README.md * readme and udpates * rn * arg to number * update docker-image * ut * fix uts * [AWS Athena] Move From Beta to GA (#30694) * Remove beta marks * Structural improvements * Validation fixes * Update code * Add release notes * Update `defaultRegion` param * Fixes * Update context output for the `aws-athena-get-query-results` command * Update output context keys * Minor fixes * Add `query_execution_id` field to results * Fix `aws-athena-get-query-execution`'s context output * Update AWS regions * Minor improvements & add unit-tests * Format YAML & bump Docker version * Update release notes with BC message * Context fixes * Delete test-playbook * Disable test-playbook * Release notes improvements * Fix test-module * Change version bump to major * Add safe code to `parse_rows_response` * Update unit-test following previous context fix * Fix tests key on YAML * Fixes & improvements * Revert breaking changes * Update context output to `Query` * Fix required param * Fixes * Add polling support for `aws-athena-get-query-results` * Bump Docker * Add missing polling parameters * Add a `QueryLimit` parameter to the `aws-athena-start-query` command * Add output fields to `aws-athena-get-query-execution` * Move polling functionality to `aws-athena-get-query-execution` * Change output of `aws-athena-start-query` to match `aws-athena-get-query-execution` * Fix validation errors * Address core-review requested changes * Fix polling condition * Remove polling from `aws-athena-get-query-execution` command * Add new `aws-athena-execute-query` polling command * Bump Docker version * Minor fixes * Update README * Update unit-tests * Bump Docker version * Update `aws-athena-execute-query` command description * Add `aws-athena-execute-query` command to release notes * Code review fixes * Update Docker version * Fix output of `aws-athena-start-query` to `Query.Query` key instead of `Query.QueryString` * Fix unit-test * Malware Investigation and Response - Added specification for integration brand for the !endpoint command. (#31399) * Specify dedicated integration brand for !endpoint command * RN * Update Docker Image To demisto/tesseract (#31410) * Updated Metadata Of Pack ImageOCR * Added release notes to pack ImageOCR * Packs/ImageOCR/Integrations/ImageOCR/ImageOCR.yml Docker image update * Fix js get incident tasks by state (#31414) * fixed js indexof * Added rn * [Marketplace Contribution] IP2LocationIO (#31302) (#31406) * "pack contribution initial commit" * Update IP2LocationIO.py * Update pack_metadata.json * Update IP2LocationIO.py * Update .secrets-ignore * Update .secrets-ignore * Update IP2LocationIO.py * Update IP2LocationIO.py * Update IP2LocationIO.yml * Update Packs/IP2LocationIO/Integrations/IP2LocationIO/IP2LocationIO.py --------- Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: IP2Location Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> * Bugfix/XSUP-30713/add-InternalIPRanges-as-playbook-input (#31329) * Pass InternalIPRanges as input for alert handling subplaybook * Add InternalIPRanges playbook input * Remove unwanted change * Fix validation error * Update release notes * Fix alert handling subplaybook to use InternalIPRanges from inputs * Fix release notes based on review comments * Bump pack from version CortexXDR to 6.0.9. --------- Co-authored-by: Content Bot * CRTX-96742: Release a new base pack (#31420) * Azure sentinel assignement options (#31419) * Azure sentinel assignement options (#31065) * Azure sentinel updates for assginment (#1) * added support to unassign incidents and assignment based on AssigneeObjectID * updated docker images and release notes * updated containers and sdk format * Update Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel.py Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> * Update Packs/AzureSentinel/Integrations/AzureSentinel/AzureSentinel.yml Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> * Update TestAzureSentinelPlaybookV2.yml revert demisto sdk format changes * Update playbook-TestAzureSentinelPlaybook.yml revert demisto-sdk format changes * undo json changes * undo demisto-sdk json changes * new version * resolve conflict * resolve conflict * resolve conflict * revert changes * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Docker Image --------- Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> Co-authored-by: MLainer1 Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * DI --------- Co-authored-by: asieberle <121243004+asieberle@users.noreply.github.com> Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> Co-authored-by: MLainer1 Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * SetGridField fixes (#31318) * SetGridField fixes * update docker * add support for incident_id * do only needed change * revert yml * docker image * revert ruff changes * revert ruff changes * fixes * fixes * fixes * RN conflicts * Update SetGridField.py * add tests * fix test * add tests * Update SetGridField_test.py * fixes CR * fix CR review,update docker * Bump pack from version CommonScripts to 1.12.57. * fix CR review * fix CR review --------- Co-authored-by: Content Bot * O365 security and compliance - search action - handle no results better (#31062) * added xsoar-saas_test_e2e_results (#31417) * Update Docker Image To demisto/auth-utils (#31431) * Updated Metadata Of Pack Troubleshoot * Added release notes to pack Troubleshoot * Packs/Troubleshoot/Scripts/CertificatesTroubleshoot/CertificatesTroubleshoot.yml Docker image update * Update Docker Image To demisto/python3 (#31427) * Updated Metadata Of Pack GCP-Enrichment-Remediation * Added release notes to pack GCP-Enrichment-Remediation * Packs/GCP-Enrichment-Remediation/Scripts/GCPProjectHierarchy/GCPProjectHierarchy.yml Docker image update * Updated Metadata Of Pack PaloAltoNetworks_Threat_Vault * Added release notes to pack PaloAltoNetworks_Threat_Vault * Packs/PaloAltoNetworks_Threat_Vault/Scripts/SetThreatVaultIncidentMarkdownRepresentation/SetThreatVaultIncidentMarkdownRepresentation.yml Docker image update * Updated Metadata Of Pack Cryptocurrency * Added release notes to pack Cryptocurrency * Packs/Cryptocurrency/Scripts/CryptoCurrenciesFormat/CryptoCurrenciesFormat.yml Docker image update * Updated Metadata Of Pack DeveloperTools * Added release notes to pack DeveloperTools * Packs/DeveloperTools/Scripts/WaitAndCompleteTask/WaitAndCompleteTask.yml Docker image update * Updated Metadata Of Pack Carbon_Black_Enterprise_Response * Added release notes to pack Carbon_Black_Enterprise_Response * Packs/Carbon_Black_Enterprise_Response/Scripts/CBWatchlists/CBWatchlists.yml Docker image update * Packs/Carbon_Black_Enterprise_Response/Scripts/CBAlerts/CBAlerts.yml Docker image update * Updated Metadata Of Pack Lokpath_Keylight * Added release notes to pack Lokpath_Keylight * Packs/Lokpath_Keylight/Scripts/KeylightCreateIssue/KeylightCreateIssue.yml Docker image update * Updated Metadata Of Pack XMatters * Added release notes to pack XMatters * Packs/XMatters/Scripts/WaitForKey/WaitForKey.yml Docker image update * Packs/XMatters/Scripts/CloseTaskSetContext/CloseTaskSetContext.yml Docker image update * Updated Metadata Of Pack AccentureCTI * Added release notes to pack AccentureCTI * Packs/AccentureCTI/Scripts/FormatACTIURL/FormatACTIURL.yml Docker image update * Updated Metadata Of Pack SymantecEndpointProtection * Added release notes to pack SymantecEndpointProtection * Packs/SymantecEndpointProtection/Scripts/SEPCheckOutdatedEndpoints/SEPCheckOutdatedEndpoints.yml Docker image update * Updated Metadata Of Pack Forcepoint * Added release notes to pack Forcepoint * Packs/Forcepoint/Scripts/FPDeleteRule/FPDeleteRule.yml Docker image update * Packs/Forcepoint/Scripts/FPSetRule/FPSetRule.yml Docker image update * Updated Metadata Of Pack AzureSentinel * Added release notes to pack AzureSentinel * Packs/AzureSentinel/Scripts/MicrosoftSentinelConvertAlertsToTable/MicrosoftSentinelConvertAlertsToTable.yml Docker image update * Packs/AzureSentinel/Scripts/MicrosoftSentinelConvertRelationsToTable/MicrosoftSentinelConvertRelationsToTable.yml Docker image update * Packs/AzureSentinel/Scripts/MicrosoftSentinelConvertEntitiesToTable/MicrosoftSentinelConvertEntitiesToTable.yml Docker image update * Packs/AzureSentinel/Scripts/MicrosoftSentinelConvertCommentsToTable/MicrosoftSentinelConvertCommentsToTable.yml Docker image update * Updated Metadata Of Pack CommonWidgets * Added release notes to pack CommonWidgets * Packs/CommonWidgets/Scripts/MyToDoTasksWidget/MyToDoTasksWidget.yml Docker image update * Packs/CommonWidgets/Scripts/FeedIntegrationErrorWidget/FeedIntegrationErrorWidget.yml Docker image update * Updated Metadata Of Pack fireeye * Added release notes to pack fireeye * Packs/fireeye/Scripts/FireEyeDetonateFile/FireEyeDetonateFile.yml Docker image update * Updated Metadata Of Pack Campaign * Added release notes to pack Campaign * Packs/Campaign/Scripts/SetPhishingCampaignDetails/SetPhishingCampaignDetails.yml Docker image update * Packs/Campaign/Scripts/GetCampaignDuration/GetCampaignDuration.yml Docker image update * Packs/Campaign/Scripts/GetCampaignIncidentsInfo/GetCampaignIncidentsInfo.yml Docker image update * Packs/Campaign/Scripts/ShowCampaignHighestSeverity/ShowCampaignHighestSeverity.yml Docker image update * Packs/Campaign/Scripts/ShowCampaignSimilarityRange/ShowCampaignSimilarityRange.yml Docker image update * Packs/Campaign/Scripts/GetCampaignLowSimilarityIncidentsInfo/GetCampaignLowSimilarityIncidentsInfo.yml Docker image update * Packs/Campaign/Scripts/IsIncidentPartOfCampaign/IsIncidentPartOfCampaign.yml Docker image update * Packs/Campaign/Scripts/GetCampaignIncidentsIdsAsOptions/GetCampaignIncidentsIdsAsOptions.yml Docker image update * Packs/Campaign/Scripts/ShowCampaignIncidentsOwners/ShowCampaignIncidentsOwners.yml Docker image update * Packs/Campaign/Scripts/CollectCampaignRecipients/CollectCampaignRecipients.yml Docker image update * Packs/Campaign/Scripts/ShowCampaignSenders/ShowCampaignSenders.yml Docker image update * Packs/Campaign/Scripts/ShowCampaignRecipients/ShowCampaignRecipients.yml Docker image update * Packs/Campaign/Scripts/GetCampaignLowerSimilarityIncidentsIdsAsOptions/GetCampaignLowerSimilarityIncidentsIdsAsOptions.yml Docker image update * Packs/Campaign/Scripts/ShowCampaignLastIncidentOccurred/ShowCampaignLastIncidentOccurred.yml Docker image update * Packs/Campaign/Scripts/SendEmailToCampaignRecipients/SendEmailToCampaignRecipients.yml Docker image update * Packs/Campaign/Scripts/PerformActionOnCampaignIncidents/PerformActionOnCampaignIncidents.yml Docker image update * Updated Metadata Of Pack RiskIQDigitalFootprint * Added release notes to pack RiskIQDigitalFootprint * Packs/RiskIQDigitalFootprint/Scripts/RiskIQDigitalFootprintAssetDetailsWidgetScript/RiskIQDigitalFootprintAssetDetailsWidgetScript.yml Docker image update * Updated Metadata Of Pack DomainToolsIrisDetect * Added release notes to pack DomainToolsIrisDetect * Packs/DomainToolsIrisDetect/Scripts/DomainToolsIrisDetectStatusUpdate/DomainToolsIrisDetectStatusUpdate.yml Docker image update * Updated Metadata Of Pack X509Certificate * Added release notes to pack X509Certificate * Packs/X509Certificate/Scripts/CertificateReputation/CertificateReputation.yml Docker image update * Updated Metadata Of Pack CarbonBlackProtect * Added release notes to pack CarbonBlackProtect * Packs/CarbonBlackProtect/Scripts/CBPFindComputer/CBPFindComputer.yml Docker image update * commit --------- Co-authored-by: israelpolishook * Fix "unexpected keyword argument" Error (#31418) * fixed bug * RN * ignore pylance error * update docker * New script: ReadQRCode (#31323) * init * json.loads on the results of extractIndicators * fix unit-tests * added docs to unit-tests * fix unit-tests * moved script to commonScripts * capitalize output key 'text' * no error for non QR code images * add RN * fix unit-tests * demo changes * added docs * Update Packs/CommonScripts/Scripts/ReadQRCode/README.md Co-authored-by: Judah Schwartz * CR changes * RN * remove trailing whitespace * build wars: round 1 * fixed 'unexpected argument' bug * unit-tests complete * Bump pack from version CommonScripts to 1.13.0. --------- Co-authored-by: Judah Schwartz Co-authored-by: Content Bot * Trend micro vision one (#31361) * Trend micro vision one (#30157) * removed microsocks Potentially harmful * imported urllib3 and removed reference to requests.packages. Updated release notes and TrendMicroVisionOne.yml * added action to add file entry from incident to sandbox and action to get result of file entry analysis status * removed redundant action to check sandbox submission status * added polling command for sandbox submissions * added unit tests for file entry to sandbox and polling for sandbox submissions * added unit tests for submit file entry and sandbox polling command * updated yml to include submit-file-entry-to-sandbox and run-sandbox-submission-polling * Update README.md Added hints for command execution order * Update README.md Updated Notes for better readability. * Update README.md Updated README.md for better readability. * updated release notes to indicate addition of submit file entry to sandbox and sandbox submission polling command * formatted files per XSOAR standards * Added command examples for V2 actions * added test_data folder containing example responses * Update README.md Added link to supported file types in submit file to sandbox and submit file entry to sandbox. * removed unused mock test case for submit file entry to sandbox and test_data folder with mock responses * Added submit file entry to sandbox and run sandbox submission polling and their respective unit tests and command_examples * added demosti.patch.object to get custom data for demisto.getFilePath in submit file entry to sandbox * updated polling comamnd per XSOAR standards and updated YAML to include polling in sandbox submissing polling command root * TrendMicroVisionOne_description * updated sandbox submission command example to include polling arg * updated yml to include polling in root of sandbox submission polling * removed unused variable declarations * updated doc string for sandbox submission polling * updated min server version to 6.2.0 in sandbox polling unit test * updated if check to differentiate between cmd instead of args * added dbotscore for sandbox submissions status and sandbox polling commands * added doc string for dbot severity helper function * Updated Vendor Name to match integration pack * updated risk to look for obj instead of str and updated release notes and updated docker image version * added dbotscore to VisionOne context data and updated YML and README.md accordingly * small context output fix * Update 1_3_0.md * updated description in YML for V3. * added pagination for suspicious/exception list as well as endpoint info and fetch incidents * updated unit test for endpoint info * updated README.md to reflect name change for 3 context outputs in get endpoint info * reverted change for get endpoint info to ensure backwards compatibility * updated docker python image in release notes * Update docker image. * Update RN. * Remove main function from unit test coverage. * corrected delete from suspicious list endpoint * updated docker image to latest per circleci test * fixed precommit error of implicitly concatenated string in regex for macaddress validation * fixed precommit error of implicitly concatenated string in regex for ipv6 validation * updated Release Notes * Add pytmv1 devdemisto image for testing * updated all actions to use pytmv1 library * added 2 new actions (get alert details and submit urls to sandbox) * updated to declare pytmv1 directly in actions instead of passing in action calls * removed commented code for pytmv1 initialization. * updated actions using pytmv1 library * added variable names for replace args and updated isolate and restore endpoint table vars * updated yml for all actions and added return_error condition for all actions * removed unused message vars * updated unit tests and added test_data folder with mock responses. * updated check_task_status unit test with correct params * updated base url for unit tests * updated var declarations to compatible union type * ran format command to format yml file * updated release notes * validated yml file * added missing default value for polling * removed commented code and wrapped digest values * added endpoint and email activity data actions and their fetch count helper functions respectively. * added unit tests for endpoint and email activity data * updated yml to include context outputs for endpoint and email activity data, added respective command examples and updated README.md * updated get_activity_data_count param for respective actions * updated README.md * added severity filter to fetch incidents * added dbotMirrorId and details to incident, added 'any' option for incident severity types and updated yml file for incidentSeverity. * added any string literal with var * updated README.md to indicate addition of 2 new actions. * updated docstrings and added comments * added comments for workbench histories and updated status check to include task class type to fetch the final task response. * removed unused vars * formatted and validated yml and README.md * updated yml for exception and suspicious list actions to correct the context outputs and updated README.md to match * updated docker image to match demsito-docker image and updated relase notes per demisto XSOAR standards. * added tmv1 url and various IPs to secrets-ignore. * updated return type for get_task_type * updated test connectivity and updated self.app reference to APP_NAME variable. * updated yml and generated new README.md * updated file path default value * updated command_examples and updated args to reference collect_files variable in collect_file action * updated yml and generated new readme, also ran command to update release notes with -bc flag * fixed submit file to sandbox unit test * Update docker image in TrendMicroVisionOneV3.yml * added breaking changes details to ReleaseNotes->4_0_0.json * Update 4_0_0.md * corrected breaking changes json file * enabled network for docker unit tests and added type:ignore for poll_time_sec * updated docker image tag to 0.6.2.79742 * updated context output for sandbox submission polling to remove report_id duplicate and replace with type. * updated 32 unit tests and added email and endpoint activity actions * corrected submit_file_to_sandbox unit test * updated yml and README.md * removed commented out code for test get endpoint information * updated endpoint and email activity data count command names and updated yml and README * added missing white space for table heading * fixed import for endpoint and email activity data * updated secretes-ignore list * updated unit test for get_endpoint_info and update dockerimage to newest. * removed top var from endpoint and email activity data count actions and updated yml and README.md accordingly. * fixed docker image tag in release notes * corrected remaining Ruff errors * added if check for str to use json loads and added input examples. Added isArray for context inputs and also updated README.md accordingly. * Added query op detailed description and examples. * replaced str if check and replaced with in-built safe_load_json method. * updated docker image to latest * Update 4_0_0.md * fixed fetch incident bug where duplicates were fetched because end date was not being set correctly. --------- Co-authored-by: yaakovpraisler Co-authored-by: Yaakov Praisler <59408745+yaakovpraisler@users.noreply.github.com> Co-authored-by: Danny_Fried Co-authored-by: Kobbi Gal <85439776+kgal-pan@users.noreply.github.com> Co-authored-by: Israel Lappe <79846863+ilappe@users.noreply.github.com> * remove pass * update docker --------- Co-authored-by: shaqnawe Co-authored-by: yaakovpraisler Co-authored-by: Yaakov Praisler <59408745+yaakovpraisler@users.noreply.github.com> Co-authored-by: Danny_Fried Co-authored-by: Kobbi Gal <85439776+kgal-pan@users.noreply.github.com> Co-authored-by: Israel Lappe <79846863+ilappe@users.noreply.github.com> Co-authored-by: ilappe * Fix MDE settings description (#31398) * updated script description * RN * updated rn * updated rn * updated rn * Bump pack from version MicrosoftDefenderAdvancedThreatProtection to 1.16.21. --------- Co-authored-by: Content Bot * Update Docker Image To demisto/netutils (#31428) * Updated Metadata Of Pack DeveloperTools * Added release notes to pack DeveloperTools * Packs/DeveloperTools/Scripts/CompareIndicators/CompareIndicators.yml Docker image update * Updated Metadata Of Pack FiltersAndTransformers * Added release notes to pack FiltersAndTransformers * Packs/FiltersAndTransformers/Scripts/IPv4Blacklist/IPv4Blacklist.yml Docker image update * Packs/FiltersAndTransformers/Scripts/IsRFC1918Address/IsRFC1918Address.yml Docker image update * Packs/FiltersAndTransformers/Scripts/IPv4Whitelist/IPv4Whitelist.yml Docker image update * Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.yml Docker image update * Bump pack from version FiltersAndTransformers to 1.2.46. * Add RN and update pack_metadata file * add README for IsNotInCidrRanges script --------- Co-authored-by: Content Bot Co-authored-by: israelpolishook * Armis fix url suffix (#31434) * Armis add suffix to base url * RN * Add UT * doc review * docker * Update Docker Image To demisto/python3 (#31439) * Updated Metadata Of Pack Active_Directory_Query * Added release notes to pack Active_Directory_Query * Packs/Active_Directory_Query/Scripts/SendEmailToManager/SendEmailToManager.yml Docker image update * Updated Metadata Of Pack ServiceNow * Added release notes to pack ServiceNow * Packs/ServiceNow/Scripts/ServiceNowUpdateIncident/ServiceNowUpdateIncident.yml Docker image update * Packs/ServiceNow/Scripts/ServiceNowQueryIncident/ServiceNowQueryIncident.yml Docker image update * Packs/ServiceNow/Scripts/ServiceNowCreateIncident/ServiceNowCreateIncident.yml Docker image update * Packs/ServiceNow/Scripts/ServiceNowAddComment/ServiceNowAddComment.yml Docker image update * Fix DS108 --------- Co-authored-by: israelpolishook * Feed Elastic: fetch in batches (#31377) * Update Docker Image To demisto/ssdeep (#31446) * Updated Metadata Of Pack CommonScripts * Added release notes to pack CommonScripts * Packs/CommonScripts/Scripts/SSDeepSimilarity/SSDeepSimilarity.yml Docker image update * Update Docker Image To demisto/taxii (#31459) * Updated Metadata Of Pack Base * Added release notes to pack Base * Packs/Base/Scripts/StixParser/StixParser.yml Docker image update * Add argument include_resolved_param to sentinelone-get-threats (#31433) * Add argument include_resolved_param to sentinelone-get-threats (#31355) * Add argument include_resolved_param to sentinelone-get-threats * fix: update pack metadatafile version * Update docker * Update 3_2_14.md * Update Packs/SentinelOne/ReleaseNotes/3_2_14.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --------- Co-authored-by: chloerongier <150173582+chloerongier@users.noreply.github.com> Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Docker Image To demisto/office-utils (#31451) * Updated Metadata Of Pack CommonScripts * Added release notes to pack CommonScripts * Packs/CommonScripts/Scripts/ConvertFile/ConvertFile.yml Docker image update * Bump pack from version CommonScripts to 1.13.2. --------- Co-authored-by: Content Bot * Update Docker Image To demisto/python3 (#31442) * Updated Metadata Of Pack CommonScripts * Added release notes to pack CommonScripts * Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.yml Docker image update * Packs/CommonScripts/Scripts/ChangeContext/ChangeContext.yml Docker image update * Packs/CommonScripts/Scripts/MarkAsNoteByTag/MarkAsNoteByTag.yml Docker image update * Packs/CommonScripts/Scripts/ExportIncidentsToCSV/ExportIncidentsToCSV.yml Docker image update * Packs/CommonScripts/Scripts/EmailReputation/EmailReputation.yml Docker image update * Packs/CommonScripts/Scripts/OnionURLReputation/OnionURLReputation.yml Docker image update * Packs/CommonScripts/Scripts/FileCreateAndUploadV2/FileCreateAndUploadV2.yml Docker image update * Packs/CommonScripts/Scripts/GetServerURL/GetServerURL.yml Docker image update * Packs/CommonScripts/Scripts/ShowLocationOnMap/ShowLocationOnMap.yml Docker image update * Packs/CommonScripts/Scripts/ExportIndicatorsToCSV/ExportIndicatorsToCSV.yml Docker image update * Packs/CommonScripts/Scripts/CheckContextValue/CheckContextValue.yml Docker image update * Packs/CommonScripts/Scripts/GetEnabledInstances/GetEnabledInstances.yml Docker image update * Packs/CommonScripts/Scripts/FileReputation/FileReputation.yml Docker image update * Packs/CommonScripts/Scripts/ConvertCountryCodeCountryName/ConvertCountryCodeCountryName.yml Docker image update * Packs/CommonScripts/Scripts/IsUrlPartOfDomain/IsUrlPartOfDomain.yml Docker image update * Packs/CommonScripts/Scripts/ServerLogs/ServerLogs.yml Docker image update * Packs/CommonScripts/Scripts/PrintRaw/PrintRaw.yml Docker image update * Packs/CommonScripts/Scripts/DisplayHTMLWithImages/DisplayHTMLWithImages.yml Docker image update * Packs/CommonScripts/Scripts/SCPPullFiles/SCPPullFiles.yml Docker image update * Packs/CommonScripts/Scripts/StopTimeToAssignOnOwnerChange/StopTimeToAssignOnOwnerChange.yml Docker image update * Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/CreateIndicatorsFromSTIX.yml Docker image update * Packs/CommonScripts/Scripts/ShowIncidentIndicators/ShowIncidentIndicators.yml Docker image update * Packs/CommonScripts/Scripts/GetDataCollectionLink/GetDataCollectionLink.yml Docker image update * Packs/CommonScripts/Scripts/PrintContext/PrintContext.yml Docker image update * Packs/CommonScripts/Scripts/ServerLogsDocker/ServerLogsDocker.yml Docker image update * Packs/CommonScripts/Scripts/GetStringsDistance/GetStringsDistance.yml Docker image update * Packs/CommonScripts/Scripts/GetDockerImageLatestTag/GetDockerImageLatestTag.yml Docker image update * Packs/CommonScripts/Scripts/GetIndicatorDBotScore/GetIndicatorDBotScore.yml Docker image update * Packs/CommonScripts/Scripts/CreateNewIndicatorsOnly/CreateNewIndicatorsOnly.yml Docker image update * Packs/CommonScripts/Scripts/ChangeRemediationSLAOnSevChange/ChangeRemediationSLAOnSevChange.yml Docker image update * Packs/CommonScripts/Scripts/DBotAverageScore/DBotAverageScore.yml Docker image update * Packs/CommonScripts/Scripts/PrintErrorEntry/PrintErrorEntry.yml Docker image update * Packs/CommonScripts/Scripts/ExtractIndicatorsFromTextFile/ExtractIndicatorsFromTextFile.yml Docker image update * Packs/CommonScripts/Scripts/UtilAnyResults/UtilAnyResults.yml Docker image update * Packs/CommonScripts/Scripts/ZipStringsArrays/ZipStringsArrays.yml Docker image update * Packs/CommonScripts/Scripts/GridFieldSetup/GridFieldSetup.yml Docker image update * Packs/CommonScripts/Scripts/GetByIncidentId/GetByIncidentId.yml Docker image update * Packs/CommonScripts/Scripts/ProvidesCommand/ProvidesCommand.yml Docker image update * Packs/CommonScripts/Scripts/ReplaceMatchGroup/ReplaceMatchGroup.yml Docker image update * Packs/CommonScripts/Scripts/VerifyCIDR/VerifyCIDR.yml Docker image update * Packs/CommonScripts/Scripts/AppendindicatorFieldWrapper/AppendindicatorFieldWrapper.yml Docker image update * Packs/CommonScripts/Scripts/URLNumberOfAds/URLNumberOfAds.yml Docker image update * Packs/CommonScripts/Scripts/FileToBase64List/FileToBase64List.yml Docker image update * Packs/CommonScripts/Scripts/GetFieldsByIncidentType/GetFieldsByIncidentType.yml Docker image update * Packs/CommonScripts/Scripts/LoadJSON/LoadJSON.yml Docker image update * Packs/CommonScripts/Scripts/URLReputation/URLReputation.yml Docker image update * Packs/CommonScripts/Scripts/IncidentFields/IncidentFields.yml Docker image update * Packs/CommonScripts/Scripts/HideFieldsOnNewIncident/HideFieldsOnNewIncident.yml Docker image update * Packs/CommonScripts/Scripts/IPReputation/IPReputation.yml Docker image update * Packs/CommonScripts/Scripts/DeduplicateValuesbyKey/DeduplicateValuesbyKey.yml Docker image update * fix DS108 * Bump pack from version CommonScripts to 1.13.2. --------- Co-authored-by: israelpolishook Co-authored-by: Content Bot * Update Docker Image To demisto/crypto (#31471) * Updated Metadata Of Pack AzureFirewall * Added release notes to pack AzureFirewall * Packs/AzureFirewall/Integrations/AzureFirewall/AzureFirewall.yml Docker image update * Updated Metadata Of Pack MicrosoftGraphIdentityandAccess * Added release notes to pack MicrosoftGraphIdentityandAccess * Packs/MicrosoftGraphIdentityandAccess/Integrations/MicrosoftGraphIdentityandAccess/MicrosoftGraphIdentityandAccess.yml Docker image update * Updated Metadata Of Pack AzureLogAnalytics * Added release notes to pack AzureLogAnalytics * Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/AzureLogAnalytics.yml Docker image update * Update Docker Image To demisto/opnsense (#31473) * Updated Metadata Of Pack OPNSense * Added release notes to pack OPNSense * Packs/OPNSense/Integrations/OPNSense/OPNSense.yml Docker image update * added logs (#31229) * added logs * Apply suggestions from code review * add rn * change image * EWS o365 eml download/incident creation inconsistencies (#31326) * EWS o365 eml download/incident creation inconsistencies (#31146) * Corrects incident occurred time to use datetime_received to match fetch email search parameters. Adjusts header validation in get item as eml and parse incident as item to match header keys in a case-insensitive way. Applies SMTP and SMTPUTF8 email policies when creating eml files based on the presence of non-ascii characters * corrects tests to expect \r\n and initialize message objects with datetime_received * corrects contenttype header check to also be lowercase * fix line length * updated release notes * test for header integrity in parse_incident_from_item function * Test for get_item_as_eml file result * reduced line lengths * updating some formatting * updated to latest version of py3ews and updated release notes to include the change * adds newline for validation * Update 1_2_32.md * updates to release notes based on feedback * another edit to the release notes * Update docker * Update docker * remove extra blank line --------- Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> Co-authored-by: omerKarkKatz <95565843+omerKarkKatz@users.noreply.github.com> * remove folder-path from test pb * Update docker * Update 1_2_32.md * Bump pack from version MicrosoftExchangeOnline to 1.2.33. --------- Co-authored-by: Isaiah Eichen Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> Co-authored-by: omerKarkKatz <95565843+omerKarkKatz@users.noreply.github.com> Co-authored-by: adi88d Co-authored-by: Content Bot * Update Docker Image To demisto/teams (#31448) * Updated Metadata Of Pack CommonScripts * Added release notes to pack CommonScripts * Packs/CommonScripts/Scripts/GenerateAsBuilt/GenerateAsBuilt.yml Docker image update * Bump pack from version CommonScripts to 1.13.2. * Bump pack from version CommonScripts to 1.13.4. --------- Co-authored-by: Content Bot * Update Docker Image To demisto/python3 (#31470) * Updated Metadata Of Pack SymantecCloudSecureWebGateway * Added release notes to pack SymantecCloudSecureWebGateway * Packs/SymantecCloudSecureWebGateway/Integrations/SymantecCloudSecureWebGatewayEventCollector/SymantecCloudSecureWebGatewayEventCollector.yml Docker image update * Updated Metadata Of Pack Lumu * Added release notes to pack Lumu * Packs/Lumu/Integrations/Lumu/Lumu.yml Docker image update * Updated Metadata Of Pack FlashpointFeed * Added release notes to pack FlashpointFeed * Packs/FlashpointFeed/Integrations/FlashpointFeed/FlashpointFeed.yml Docker image update * Updated Metadata Of Pack Wiz * Added release notes to pack Wiz * Packs/Wiz/Integrations/Wiz/Wiz.yml Docker image update * Updated Metadata Of Pack AbnormalSecurity * Added release notes to pack AbnormalSecurity * Packs/AbnormalSecurity/Integrations/AbnormalSecurity/AbnormalSecurity.yml Docker image update * Updated Metadata Of Pack FeedLOLBAS * Added release notes to pack FeedLOLBAS * Packs/FeedLOLBAS/Integrations/FeedLOLBAS/FeedLOLBAS.yml Docker image update * Updated Metadata Of Pack Hackuity * Added release notes to pack Hackuity * Packs/Hackuity/Integrations/Hackuity/Hackuity.yml Docker image update * Updated Metadata Of Pack Grafana * Added release notes to pack Grafana * Packs/Grafana/Integrations/Grafana/Grafana.yml Docker image update * Updated Metadata Of Pack Binalyze * Added release notes to pack Binalyze * Packs/Binalyze/Integrations/BinalyzeAIR/BinalyzeAIR.yml Docker image update * Updated Metadata Of Pack ServiceDeskPlus * Added release notes to pack ServiceDeskPlus * Packs/ServiceDeskPlus/Integrations/ServiceDeskPlus/ServiceDeskPlus.yml Docker image update * Updated Metadata Of Pack Oracle_IAM * Added release notes to pack Oracle_IAM * Packs/Oracle_IAM/Integrations/OracleIAM/OracleIAM.yml Docker image update * Updated Metadata Of Pack VMwareWorkspaceONEUEM * Added release notes to pack VMwareWorkspaceONEUEM * Packs/VMwareWorkspaceONEUEM/Integrations/VMwareWorkspaceONEUEM/VMwareWorkspaceONEUEM.yml Docker image update * Updated Metadata Of Pack SalesforceFusion * Added release notes to pack SalesforceFusion * Packs/SalesforceFusion/Integrations/SalesforceFusionIAM/SalesforceFusionIAM.yml Docker image update * Updated Metadata Of Pack RecordedFuture * Added release notes to pack RecordedFuture * Packs/RecordedFuture/Integrations/RecordedFuture/RecordedFuture.yml Docker image update * Packs/RecordedFuture/Integrations/RecordedFutureLists/RecordedFutureLists.yml Docker image update * Fix DS108 --------- Co-authored-by: israelpolishook * CS Falcon - Add batch_id argument to run_command (#31394) * added batch_id argument * unit tests * updated unit tests and docker image * RN * updated README * Update Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py Co-authored-by: EyalPintzov <91007713+eyalpalo@users.noreply.github.com> * Bump pack from version CrowdStrikeFalcon to 1.12.8. * updated the timeout * updated the timeout * updated the timeout * docker image update --------- Co-authored-by: EyalPintzov <91007713+eyalpalo@users.noreply.github.com> Co-authored-by: Content Bot * Update Docker Image To demisto/auth-utils (#31472) * Updated Metadata Of Pack Cylance_Protect * Added release notes to pack Cylance_Protect * Packs/Cylance_Protect/Integrations/Cylance_Protect_v2/Cylance_Protect_v2.yml Docker image update * Updated Metadata Of Pack Zoom * Added release notes to pack Zoom * Packs/Zoom/Integrations/ZoomEventCollector/ZoomEventCollector.yml Docker image update * Updated Metadata Of Pack Silverfort * Added release notes to pack Silverfort * Packs/Silverfort/Integrations/Silverfort/Silverfort.yml Docker image update * Updated Metadata Of Pack AzureDataExplorer * Added release notes to pack AzureDataExplorer * Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer.yml Docker image update * Updated Metadata Of Pack MicrosoftManagementActivity * Added release notes to pack MicrosoftManagementActivity * Packs/MicrosoftManagementActivity/Integrations/MicrosoftManagementActivity/MicrosoftManagementActivity.yml Docker image update * Updated Metadata Of Pack Box * Added release notes to pack Box * Packs/Box/Integrations/BoxEventsCollector/BoxEventsCollector.yml Docker image update * Packs/Box/Integrations/BoxV2/BoxV2.yml Docker image update * exclude Silverfort pack --------- Co-authored-by: israelpolishook * Update Docker Image To demisto/parse-emails (#31457) * Updated Metadata Of Pack CommonScripts * Added release notes to pack CommonScripts * Packs/CommonScripts/Scripts/ParseEmailFilesV2/ParseEmailFilesV2.yml Docker image update * Bump pack from version CommonScripts to 1.13.2. * Bump pack from version CommonScripts to 1.13.4. * Bump pack from version CommonScripts to 1.13.5. --------- Co-authored-by: Content Bot * update condition for create link to jira for contributions prs (#31475) * bug fix (#31476) * save fix * save fix * save debug * save debug * [SaaS Security Event Collector] - logs & docs improvements (#31474) * [SaaS Security Event Collector] - logs improvements * docs updates * rn * pre-commit fixes * rn * rn * Added context output and indicator tagging to CreateIndicatorsFromStix (#31485) * Added context output and indicator tagging to CreateIndicatorsFromStix (#31140) * Added context output and tagging to CreateIndicatorsFromSTIX.py * Removed Spaces in CommandResults * Added Release Note Bumped Up Version to 1.12.50 * Update Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/CreateIndicatorsFromSTIX.py Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * Update Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/CreateIndicatorsFromSTIX.py Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * Update Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/CreateIndicatorsFromSTIX.yml Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * Update Packs/CommonScripts/ReleaseNotes/1_12_50.md Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * Update Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/CreateIndicatorsFromSTIX.py Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * fixes in CreateIndicatorsFromSTIX.py * Updated YML * Updated CreateIndicatorsFromSTIX_test.py * Updated CreateIndicatorsFromSTIX_test.py * Updated Docker Image Version * Updated Release notes to align with docker version * Added Tags to context output. * Added outputs to CreateIndicatorsFromSTIX.yml * Bumped up Docker Image version in Release Note and YML Added additional asserts in test * Adjusted Version * Updated README.md * Updated CreateIndicatorsFromSTIX.yml with description periods. * Added CONTRIBUTORS.json * Deleted CONTRIBUTORS.json * Update 1_13_5.md * Update CreateIndicatorsFromSTIX.yml * Update README.md * Update README.md * Update Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/CreateIndicatorsFromSTIX.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/CreateIndicatorsFromSTIX.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/CreateIndicatorsFromSTIX.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonScripts/Scripts/CreateIndicatorsFromSTIX/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --------- Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * merge from master --------- Co-authored-by: Martin Ohl Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> Co-authored-by: adi88d * Update Docker Image To demisto/sklearn (#31458) * Updated Metadata Of Pack Phishing * Added release notes to pack Phishing * Packs/Phishing/Scripts/FindDuplicateEmailIncidents/FindDuplicateEmailIncidents.yml Docker image update --------- Co-authored-by: israelpoli <72099621+israelpoli@users.noreply.github.com> * Update Docker Image To demisto/chromium (#31460) * Updated Metadata Of Pack ExpanseV2 * Added release notes to pack ExpanseV2 * Packs/ExpanseV2/Scripts/ExpanseGenerateIssueMapWidgetScript/ExpanseGenerateIssueMapWidgetScript.yml Docker image update --------- Co-authored-by: israelpoli <72099621+israelpoli@users.noreply.github.com> * Fixed auto closing tickets in service now (#31194) * fix * tests * rn * format * rn * Bump pack from version ServiceNow to 2.5.48. * revert and bug fix * cr --------- Co-authored-by: Content Bot * Fix email com (#31481) * fixes * added rn * update docker * update tests * cr fixes * quick fix * Update Docker Image To demisto/readpdf (#31507) * Updated Metadata Of Pack CommonScripts * Added release notes to pack CommonScripts * Packs/CommonScripts/Scripts/PDFUnlocker/PDFUnlocker.yml Docker image update * Packs/CommonScripts/Scripts/ReadPDFFileV2/ReadPDFFileV2.yml Docker image update * Replacing Qradar search PB with the representative command (#31328) * Changed the QradarSearch PB to the relavent command * RN * RN * Changed the PB to be deprecated * Changed keys according to the new output * Resolve conflicts * Removed un required tests * Changed from simple to complex * Bump pack from version CommonPlaybooks to 2.4.40. * Added BC + updated the PB readme files * Added BC + updated the PB readme files * Bump pack from version QRadar to 2.4.46. * removed un-used script arguments ( ChangeContext script) --------- Co-authored-by: Content Bot * [PAN-OS Policy Optimizer] Add pagination support to `pan-os-po-get-rules` (#31402) * Improve readability * Add pagination to `policy_optimizer_get_rules` * Readable output improvements * Fix `argToBoolean` resulting in error if the optional `exclude` parameter is missing * Add pagination parameters * ruff * Update README * Add release-notes and bump version * Fix mypy issues * Minor release-notes fix * Fix unit-tests * Add `page` parameter * Add pagination unit-test * Bump Docker version * adding xsoar-saas_test_e2e_results to needs list (#31510) * Small fixes to folder names (#31019) * OpenCVE throws an error when trying to enrich a CVE (#31482) OpenCVE throws an error when trying to enrich a CVE #31482 * Remove generic polling task (#31411) * generic polling task was removed and read me file created * Release notes update * release notes update * old playbook deprecated and new version created * release notes added * added image to the old playbook version * deprecated for the playbook * RN updated * added image * removed unnecessary tasks * added more outputs * RN updated * added description * image replaced * added an instance to a test PB * removed tests instances removed from PB this test * removed tests --------- Co-authored-by: Sasha Sokolovich <88268646+ssokolovich@users.noreply.github.com> Co-authored-by: ssokolovich * CTF fixes (#31483) * - Fixed hints and tasks descriptions - added the "LastArrayElement" to all check your answers tasks ( in case the user will re-open the data collection task and submit the answer through it). * RN * Fix command analysis PB (#31461) * Added another path so the PB won't skip the entire branch. * Added another path so the PB won't skip the entire branch. * Removed all tests * fix validations * Bump pack from version CommonPlaybooks to 2.4.41. * Updated RN description * Updated RN description --------- Co-authored-by: Content Bot * Added Plug and Fetch tags (#31136) * Slack bb fixes (#31393) * install specific version of neo4j in ci (#31520) * [Marketplace Contribution] QR Code Read and Decode (offline) (#31523) * [Marketplace Contribution] QR Code Read and Decode (offline) (#31099) * "pack contribution initial commit" * Update Qrcodereader.py fixed for Multi * move script to QRCodeReader pack * format yml file * update RN * add CONTRIBUTORS.json fix flake8 --------- Co-authored-by: Joerg Stephan <7138386+johestephan@users.noreply.github.com> Co-authored-by: adi88d Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * add disable=no-member --------- Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: Joerg Stephan <7138386+johestephan@users.noreply.github.com> Co-authored-by: adi88d Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> * Update Elasticsearch pack README.md (#31514) * Update incident occurred time (#31522) * Update incident occurred time (#31404) * updating occurred time for incidents * release notes * validation fixes * nit * fix formatting * update RN --------- Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> Co-authored-by: adi88d * add new line * update RN * remove whitespace from blank line --------- Co-authored-by: William Olyslager Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> Co-authored-by: adi88d * [Azure Compute v2] Fixed the API version (#31517) * First sso fix ip task (#31512) * change skipifunavailable to true - !ip * RN after change skipifunavailable to true - !ip * removed unessary poetry changes * removed unessary poetry changes * replace \ * remove file * update docker * rn * fix dn also * new rn * Add comment --------- Co-authored-by: RotemAmit Co-authored-by: eli sharf <57587340+esharf@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> Co-authored-by: eepstain <116078117+eepstain@users.noreply.github.com> Co-authored-by: content-bot <55035720+content-bot@users.noreply.github.com> Co-authored-by: zdrouse Co-authored-by: adi88d Co-authored-by: Adi Daud <46249224+adi88d@users.noreply.github.com> Co-authored-by: Guy Afik <53861351+GuyAfik@users.noreply.github.com> Co-authored-by: Yuval Hayun <70104171+YuvHayun@users.noreply.github.com> Co-authored-by: omerKarkKatz <95565843+omerKarkKatz@users.noreply.github.com> Co-authored-by: TalNos <112805149+TalNos@users.noreply.github.com> Co-authored-by: Menachem Weinfeld <90556466+mmhw@users.noreply.github.com> Co-authored-by: Content Bot Co-authored-by: Ben Melamed Co-authored-by: Crest Data Systems <60967033+crestdatasystems@users.noreply.github.com> Co-authored-by: crestdatasystems Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> Co-authored-by: John <40349459+BigEasyJ@users.noreply.github.com> Co-authored-by: yasta5 <112320333+yasta5@users.noreply.github.com> Co-authored-by: Shahaf Ben Yakir <44666568+ShahafBenYakir@users.noreply.github.com> Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> Co-authored-by: cweltPA <129675344+cweltPA@users.noreply.github.com> Co-authored-by: israelpolishook Co-authored-by: Karina Fishman <147307864+karinafishman@users.noreply.github.com> Co-authored-by: Sasha Sokolovich <88268646+ssokolovich@users.noreply.github.com> Co-authored-by: Moshe Galitzky <112559840+moishce@users.noreply.github.com> Co-authored-by: Yehuda Rosenberg <90599084+RosenbergYehuda@users.noreply.github.com> Co-authored-by: Moshe Eichler <78307768+MosheEichler@users.noreply.github.com> Co-authored-by: Dean Arbel Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: Sapir Shuker <49246861+sapirshuker@users.noreply.github.com> Co-authored-by: David Uhrlaub <90627446+rurhrlaub@users.noreply.github.com> Co-authored-by: suraj-metron <87964764+suraj-metron@users.noreply.github.com> Co-authored-by: Jasmine Beilin <71636766+JasBeilin@users.noreply.github.com> Co-authored-by: Arad Carmi <62752352+AradCarmi@users.noreply.github.com> Co-authored-by: DinaMeylakh <72339665+DinaMeylakh@users.noreply.github.com> Co-authored-by: William Olyslager Co-authored-by: sapirshuker Co-authored-by: JudithB <132264628+jbabazadeh@users.noreply.github.com> Co-authored-by: Jacob Levy <129657918+jlevypaloalto@users.noreply.github.com> Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> Co-authored-by: ilaner <88267954+ilaner@users.noreply.github.com> Co-authored-by: ilan Co-authored-by: Chait A <112722030+capanw@users.noreply.github.com> Co-authored-by: ilappe Co-authored-by: TalGumi <101499620+TalGumi@users.noreply.github.com> Co-authored-by: okarkkatz Co-authored-by: Jas Beilin Co-authored-by: Erez FelmanDar <102903097+efelmandar@users.noreply.github.com> Co-authored-by: Shmuel Kroizer <69422117+shmuel44@users.noreply.github.com> Co-authored-by: Yaakov Praisler <59408745+yaakovpraisler@users.noreply.github.com> Co-authored-by: samuelFain <65926551+samuelFain@users.noreply.github.com> Co-authored-by: Martin Ohl Co-authored-by: Koby Meir Co-authored-by: Mai Morag <81917647+maimorag@users.noreply.github.com> Co-authored-by: EyalPintzov <91007713+eyalpalo@users.noreply.github.com> Co-authored-by: Ido van Dijk <43602124+idovandijk@users.noreply.github.com> Co-authored-by: ArikDay <115150768+ArikDay@users.noreply.github.com> Co-authored-by: anas-yousef <44998563+anas-yousef@users.noreply.github.com> Co-authored-by: Christopher Hultin Co-authored-by: Yuval Cohen <86777474+yucohen@users.noreply.github.com> Co-authored-by: arikday Co-authored-by: NicBunn-PlutoFlume <112942358+NicBunn-PlutoFlume@users.noreply.github.com> Co-authored-by: israelpoli <72099621+israelpoli@users.noreply.github.com> Co-authored-by: Chanan Welt Co-authored-by: Vipul Kaneriya <50216620+vipulkaneriya@users.noreply.github.com> Co-authored-by: MLainer1 Co-authored-by: syed-loginsoft <97145640+syed-loginsoft@users.noreply.github.com> Co-authored-by: Danny Fried Co-authored-by: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Co-authored-by: sharonfi99 <147984773+sharonfi99@users.noreply.github.com> Co-authored-by: Michael Yochpaz <8832013+MichaelYochpaz@users.noreply.github.com> Co-authored-by: IP2Location Co-authored-by: Liron Michalevich <73780437+lmichalevich@users.noreply.github.com> Co-authored-by: asieberle <121243004+asieberle@users.noreply.github.com> Co-authored-by: Judah Schwartz Co-authored-by: shaqnawe Co-authored-by: yaakovpraisler Co-authored-by: Kobbi Gal <85439776+kgal-pan@users.noreply.github.com> Co-authored-by: Israel Lappe <79846863+ilappe@users.noreply.github.com> Co-authored-by: chloerongier <150173582+chloerongier@users.noreply.github.com> Co-authored-by: Isaiah Eichen Co-authored-by: Dror Avrahami Co-authored-by: ssokolovich Co-authored-by: Andrew Shamah <42912128+amshamah419@users.noreply.github.com> Co-authored-by: Joerg Stephan <7138386+johestephan@users.noreply.github.com> Co-authored-by: OmriItzhak <115150792+OmriItzhak@users.noreply.github.com> --- .../Active_Directory_Query/Active_Directory_Query.py | 3 +++ Packs/Active_Directory_Query/ReleaseNotes/1_6_30.md | 6 ++++++ Packs/Active_Directory_Query/pack_metadata.json | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 Packs/Active_Directory_Query/ReleaseNotes/1_6_30.md diff --git a/Packs/Active_Directory_Query/Integrations/Active_Directory_Query/Active_Directory_Query.py b/Packs/Active_Directory_Query/Integrations/Active_Directory_Query/Active_Directory_Query.py index 5875672fb282..887fd8cabb01 100644 --- a/Packs/Active_Directory_Query/Integrations/Active_Directory_Query/Active_Directory_Query.py +++ b/Packs/Active_Directory_Query/Integrations/Active_Directory_Query/Active_Directory_Query.py @@ -400,6 +400,9 @@ def get_user_dn_by_email(default_base_dn, email): def modify_user_ou(dn, new_ou): assert connection is not None cn = dn.split(',', 1)[0] + # removing // to fix customers bug + cn = cn.replace('\\', '') + dn = dn.replace('\\', '') success = connection.modify_dn(dn, cn, new_superior=new_ou) return success diff --git a/Packs/Active_Directory_Query/ReleaseNotes/1_6_30.md b/Packs/Active_Directory_Query/ReleaseNotes/1_6_30.md new file mode 100644 index 000000000000..261643f3215d --- /dev/null +++ b/Packs/Active_Directory_Query/ReleaseNotes/1_6_30.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Active Directory Query v2 + +- Fixed an issue where the ***ad-modify-user-ou*** command changed the CN value. \ No newline at end of file diff --git a/Packs/Active_Directory_Query/pack_metadata.json b/Packs/Active_Directory_Query/pack_metadata.json index c5b7d124933e..342196ddebde 100644 --- a/Packs/Active_Directory_Query/pack_metadata.json +++ b/Packs/Active_Directory_Query/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Active Directory Query", "description": "Active Directory Query integration enables you to access and manage Active Directory objects (users, contacts, and computers).", "support": "xsoar", - "currentVersion": "1.6.29", + "currentVersion": "1.6.30", "author": "Cortex XSOAR", "url": "", "email": "", From 026bd6f3aa8d95b4d7f58b281465414c863d1d02 Mon Sep 17 00:00:00 2001 From: eepstain <116078117+eepstain@users.noreply.github.com> Date: Thu, 22 Feb 2024 09:50:58 +0200 Subject: [PATCH 065/272] Update MS DNS README (#33053) * Updated README * Update Packs/MicrosoftDNS/README.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- Packs/MicrosoftDNS/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Packs/MicrosoftDNS/README.md b/Packs/MicrosoftDNS/README.md index caa17d96cc6f..a585d9fbee1f 100644 --- a/Packs/MicrosoftDNS/README.md +++ b/Packs/MicrosoftDNS/README.md @@ -25,7 +25,10 @@ You can configure the vendor and product by replacing [vendor]\_[product]\_raw w When configuring the instance, you should use a yml file that configures the vendor and product, as shown in the below configuration for the Microsoft DNS product. **Pay Attention**: -When using this pack there are two integrations available for it. +* There are two integrations available in this content pack. +* Timestamp log ingestion is supported in either of the following formats in UTC (00:00) time. + - *%m/%d/%Y %I:%M:%S %p* + - *%d/%m/%Y %H:%M:%S* * ***As enrichment, forwarding DNS Audit logs is supported via Winlogbeat*** From 1e127860609ab84be4c9c10cf25b02da20f548a9 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Thu, 22 Feb 2024 10:45:21 +0200 Subject: [PATCH 066/272] Update `demisto/teams` 0-10 coverage rate (#32633) * upgrade images * update RN * Bump pack from version Workday to 1.4.11. --------- Co-authored-by: Content Bot --- .../WorkdayIAMEventsGenerator/WorkdayIAMEventsGenerator.yml | 2 +- Packs/Workday/ReleaseNotes/1_4_11.md | 6 ++++++ Packs/Workday/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/Workday/ReleaseNotes/1_4_11.md diff --git a/Packs/Workday/Integrations/WorkdayIAMEventsGenerator/WorkdayIAMEventsGenerator.yml b/Packs/Workday/Integrations/WorkdayIAMEventsGenerator/WorkdayIAMEventsGenerator.yml index bf5d3e70830b..a70c55d83314 100644 --- a/Packs/Workday/Integrations/WorkdayIAMEventsGenerator/WorkdayIAMEventsGenerator.yml +++ b/Packs/Workday/Integrations/WorkdayIAMEventsGenerator/WorkdayIAMEventsGenerator.yml @@ -63,7 +63,7 @@ script: name: workday-generate-terminate-event - description: Reset the integration context to fetch the first run reports. name: initialize-context - dockerimage: demisto/teams:1.0.0.14902 + dockerimage: demisto/teams:1.0.0.86482 longRunning: true longRunningPort: true script: '-' diff --git a/Packs/Workday/ReleaseNotes/1_4_11.md b/Packs/Workday/ReleaseNotes/1_4_11.md new file mode 100644 index 000000000000..e4b4c58d06ce --- /dev/null +++ b/Packs/Workday/ReleaseNotes/1_4_11.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Workday IAM Event Generator (Beta) + +- Updated the Docker image to: *demisto/teams:1.0.0.86482*. diff --git a/Packs/Workday/pack_metadata.json b/Packs/Workday/pack_metadata.json index 122a314edc70..7ddaa7bf387a 100644 --- a/Packs/Workday/pack_metadata.json +++ b/Packs/Workday/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Workday", "description": "Workday offers enterprise-level software solutions for financial management, human resources, and planning.", "support": "xsoar", - "currentVersion": "1.4.10", + "currentVersion": "1.4.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From ea5c2e941ab1f5fbd9b24b2d2c75cb014d786703 Mon Sep 17 00:00:00 2001 From: Arad Carmi <62752352+AradCarmi@users.noreply.github.com> Date: Thu, 22 Feb 2024 10:54:11 +0200 Subject: [PATCH 067/272] Updated repo name from the Github Context (#33055) --- .github/workflows/trigger-contribution-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trigger-contribution-build.yml b/.github/workflows/trigger-contribution-build.yml index b51464014b9f..018ff010b997 100644 --- a/.github/workflows/trigger-contribution-build.yml +++ b/.github/workflows/trigger-contribution-build.yml @@ -24,7 +24,7 @@ jobs: PR_NUMBER: ${{ github.event.pull_request.number }} BASE_BRANCH: ${{ github.event.pull_request.base.ref }} CONTRIB_BRANCH: ${{ github.event.pull_request.head.label }} - CONTRIB_REPO: ${{ github.event.repository.name }} + CONTRIB_REPO: ${{ github.event.pull_request.head.repo.name }} USERNAME: ${{ secrets.SECRET_CHECK_USER_NG }} PASSWORD: ${{ secrets.SECRET_CHECK_PASS_NG }} GOLD_SERVER_URL: ${{ secrets.GOLD_SERVER_URL_NG }} From 6922ab5967602043f8a9433b2e36d7787a3716f8 Mon Sep 17 00:00:00 2001 From: samuelFain <65926551+samuelFain@users.noreply.github.com> Date: Thu, 22 Feb 2024 11:56:56 +0200 Subject: [PATCH 068/272] [EWSO365] Handle corrupt Message-ID header (#32776) * Add handling of Message-ID header coming from attachment.item.headers Add debug logs * Update malformed Message-ID handling to also consider escape characters * Update handle_incorrect_message_id to consider escape characters Update RN; Update docker image * Add UT; Update docker image ref * Update release notes * Replace string.find with regex search * Remove XSUP-32660 debug logs * Add test use cases * Apply suggestions from code review Co-authored-by: dorschw <81086590+dorschw@users.noreply.github.com> * Remove redundant IndexError handling * Update docker image * Update release notes --------- Co-authored-by: dorschw <81086590+dorschw@users.noreply.github.com> --- .../Integrations/EWSO365/EWSO365.py | 43 ++++++++++++++----- .../Integrations/EWSO365/EWSO365.yml | 2 +- .../Integrations/EWSO365/EWSO365_test.py | 30 ++++++++++++- .../ReleaseNotes/1_2_40.md | 8 ++++ .../pack_metadata.json | 2 +- 5 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 Packs/MicrosoftExchangeOnline/ReleaseNotes/1_2_40.md diff --git a/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365.py b/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365.py index 815b93e27440..45d4951a7f85 100644 --- a/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365.py +++ b/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365.py @@ -2037,7 +2037,7 @@ def get_item_as_eml(client: EWSClient, item_id, target_mailbox=None): # pra return None -def handle_attached_email_with_incorrect_id(attached_email: Message): +def handle_attached_email_with_incorrect_message_id(attached_email: Message): """This function handles a malformed Message-ID value which can be returned in the header of certain email objects. This issue happens due to a current bug in "email" library and further explained in XSUP-32074. Public issue link: https://github.com/python/cpython/issues/105802 @@ -2053,12 +2053,14 @@ def handle_attached_email_with_incorrect_id(attached_email: Message): for i in range(len(attached_email._headers)): if attached_email._headers[i][0] == "Message-ID": message_id = attached_email._headers[i][1] + demisto.debug(f'Handling Message-ID header, {message_id=}.') try: - if message_id.endswith("]>") and message_id.startswith("<["): - demisto.debug(f"Fixing invalid {message_id=} attachment header by removing its square bracket \ - wrapper (see XSUP-32074 for further information)") + message_id_value = handle_incorrect_message_id(message_id) + if message_id_value != message_id: + # If the Message-ID header was fixed in the context of this function + # the header will be replaced in _headers list attached_email._headers.pop(i) - message_id_value = f"<{message_id[2:-2]}>" + attached_email._headers.append(("Message-ID", message_id_value)) except Exception as e: # The function is designed to handle a specific format error for the Message-ID header @@ -2069,12 +2071,24 @@ def handle_attached_email_with_incorrect_id(attached_email: Message): demisto.debug(f"Invalid {message_id=}, Error: {e}") break break - if message_id_value: - # If the Message-ID header was fixed in the context of this function, it will be inserted again to the _headers list - attached_email._headers.append(("Message-ID", message_id_value)) return attached_email +def handle_incorrect_message_id(message_id: str) -> str: + """ + Use regex to identify and correct one of the following invalid message_id formats: + 1. '<[message_id]>' --> '' + 2. '\r\n\t<[message_id]>' --> '\r\n\t' + If no necessary changes identified the original 'message_id' argument value is returned. + """ + if re.search("\<\[.*\]\>", message_id): + # find and replace "<[" with "<" and "]>" with ">" + fixed_message_id = re.sub(r'<\[(.*?)\]>', r'<\1>', message_id) + demisto.debug('Fixed message id {message_id} to {fixed_message_id}') + return fixed_message_id + return message_id + + def parse_incident_from_item(item): # pragma: no cover """ Parses an incident from an item @@ -2184,7 +2198,7 @@ def parse_incident_from_item(item): # pragma: no cover if attachment.item.headers: # compare header keys case-insensitive attached_email_headers = [] - attached_email = handle_attached_email_with_incorrect_id(attached_email) + attached_email = handle_attached_email_with_incorrect_message_id(attached_email) for h, v in attached_email.items(): if not isinstance(v, str): try: @@ -2203,7 +2217,16 @@ def parse_incident_from_item(item): # pragma: no cover and header.name.lower() != "content-type" ): try: - attached_email.add_header(header.name, header.value) + if header.name.lower() == "message-id": + """ Handle a case where a Message-ID header was NOT already in attached_email, + and instead is coming from attachment.item.headers. + Meaning it wasn't handled in handle_attached_email_with_incorrect_message_id function + and instead it is handled here using handle_incorrect_message_id function.""" + correct_message_id = handle_incorrect_message_id(header.value) + if (header.name.lower(), correct_message_id) not in attached_email_headers: + attached_email.add_header(header.name, correct_message_id) + else: + attached_email.add_header(header.name, header.value) except ValueError as err: if "There may be at most" not in str(err): raise err diff --git a/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365.yml b/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365.yml index dd04831bbd9b..f4a9c2b50362 100644 --- a/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365.yml +++ b/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365.yml @@ -959,7 +959,7 @@ script: - description: Run this command if for some reason you need to rerun the authentication process. name: ews-auth-reset arguments: [] - dockerimage: demisto/py3ews:1.0.0.86480 + dockerimage: demisto/py3ews:1.0.0.88266 isfetch: true script: '' subtype: python3 diff --git a/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365_test.py b/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365_test.py index 4fd460a8f021..cd98f47b0513 100644 --- a/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365_test.py +++ b/Packs/MicrosoftExchangeOnline/Integrations/EWSO365/EWSO365_test.py @@ -18,8 +18,9 @@ get_expanded_group, get_item_as_eml, get_searchable_mailboxes, - handle_attached_email_with_incorrect_id, + handle_attached_email_with_incorrect_message_id, handle_html, + handle_incorrect_message_id, handle_transient_files, parse_incident_from_item, parse_item_as_dict, @@ -864,4 +865,29 @@ def test_handle_attached_email_with_incorrect_id(mocker, headers, expected_forma email_policy = SMTP attached_email = email.message_from_bytes(mime_content, policy=email_policy) attached_email._headers = headers - assert handle_attached_email_with_incorrect_id(attached_email)._headers == expected_formatted_headers + assert handle_attached_email_with_incorrect_message_id(attached_email)._headers == expected_formatted_headers + + +@pytest.mark.parametrize("message_id, expected_message_id_output", [ + pytest.param('', '', id="valid message_id 1"), + pytest.param('', '', id="valid message_id 2"), + pytest.param('<>]message_id>', '<>]message_id>', id="valid message_id 3"), + pytest.param('<[message_id]>', '', id="invalid message_id"), + pytest.param('\r\n\t', '\r\n\t', id="valid message_id with escape chars"), + pytest.param('\r\n\t<[message_id]>', '\r\n\t', id="invalid message_id with escape chars"), +]) +def test_handle_incorrect_message_id(message_id, expected_message_id_output): + """ + Given: + - case 1: valid Message-ID header value in attached email object + - case 1: invalid Message-ID header value in attached email object + - case 3: a Message-ID header value format which is not tested in the context of handle_attached_email_with_incorrect_id + When: + - fetching email which have an attached email with Message-ID header + Then: + - case 1: verify the header in the correct format + - case 2: correct the invalid Message-ID header value + - case 3: return the header value without without further handling + + """ + assert handle_incorrect_message_id(message_id) == expected_message_id_output diff --git a/Packs/MicrosoftExchangeOnline/ReleaseNotes/1_2_40.md b/Packs/MicrosoftExchangeOnline/ReleaseNotes/1_2_40.md new file mode 100644 index 000000000000..204221ee002f --- /dev/null +++ b/Packs/MicrosoftExchangeOnline/ReleaseNotes/1_2_40.md @@ -0,0 +1,8 @@ + +#### Integrations + +##### EWS O365 +- Updated the Docker image to: *demisto/py3ews:1.0.0.88266*. + +- Fixed an issue where fetching failed when email attachments had headers with an invalid format containing escape characters (`\r\n\t<[invalid_value]>` instead of `\r\n\t`), by removing the square brackets. + diff --git a/Packs/MicrosoftExchangeOnline/pack_metadata.json b/Packs/MicrosoftExchangeOnline/pack_metadata.json index e6d3be3e88c5..aa78201704bd 100644 --- a/Packs/MicrosoftExchangeOnline/pack_metadata.json +++ b/Packs/MicrosoftExchangeOnline/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Exchange Online", "description": "Exchange Online and Office 365 (mail)", "support": "xsoar", - "currentVersion": "1.2.39", + "currentVersion": "1.2.40", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 712bd0d3eaa042b26f45f575b97d19d6d7507697 Mon Sep 17 00:00:00 2001 From: samuelFain <65926551+samuelFain@users.noreply.github.com> Date: Thu, 22 Feb 2024 14:12:40 +0200 Subject: [PATCH 069/272] [Native Image] Release py3-native 8.6 (#32977) * Update native image versions Reference for 8.6 will be updated once available * Update native image 8.6 reference * Update native image ref * Apply suggestions from code review Co-authored-by: Guy Afik <53861351+GuyAfik@users.noreply.github.com> * Remove native:8.4 * Remove trailing comma in json file --------- Co-authored-by: Guy Afik <53861351+GuyAfik@users.noreply.github.com> --- Tests/docker_native_image_config.json | 62 +++++---------------------- 1 file changed, 11 insertions(+), 51 deletions(-) diff --git a/Tests/docker_native_image_config.json b/Tests/docker_native_image_config.json index d884de2b1f26..471cd0dfc482 100644 --- a/Tests/docker_native_image_config.json +++ b/Tests/docker_native_image_config.json @@ -1,37 +1,6 @@ { "native_images":{ - "native:8.3": { - "supported_docker_images": [ - "python3", - "python3-deb", - "python3-ubi", - "py3-tools", - "py3-tools-ubi", - "crypto", - "readpdf", - "parse-emails", - "docxpy", - "sklearn", - "pandas", - "ippysocks-py3", - "oauthlib", - "unzip", - "py3ews", - "taxii2", - "pan-os-python", - "slackv3", - "google-api-py3", - "boto3py3", - "pyjwt3", - "joe-security", - "slack", - "office-utils", - "chromium", - "tesseract" - ], - "docker_ref": "demisto/py3-native:8.3.0.73063" - }, - "native:8.4":{ + "native:8.6":{ "supported_docker_images":[ "python3", "python3-deb", @@ -62,7 +31,7 @@ "netutils", "auth-utils" ], - "docker_ref": "demisto/py3-native:8.4.0.75024" + "docker_ref": "demisto/py3-native:8.6.0.88042" }, "native:dev":{ "supported_docker_images":[ @@ -133,8 +102,7 @@ "id":"Symantec MSS", "reason":"issue: CIAC-9119 - [Symantec MSS] Module 'OpenSSL.crypto' has deprecated 'load_pkcs12' member", "ignored_native_images":[ - "native:8.4", - "native:8.3", + "native:8.6", "native:dev", "native:candidate" ] @@ -143,8 +111,7 @@ "id":"FetchIndicatorsFromFile", "reason":"issue: CIAC-5243 - ElementTree object (xml) in python3.9 has getiterator attribute while in python 3.10 this attribute does not exist - causing unit tests failures.", "ignored_native_images":[ - "native:8.4", - "native:8.3", + "native:8.6", "native:dev", "native:candidate" ] @@ -153,8 +120,7 @@ "id":"Rasterize", "reason":"Issue: CRTX-72338 and CIAC-7694", "ignored_native_images":[ - "native:8.4", - "native:8.3", + "native:8.6", "native:candidate" ] }, @@ -162,8 +128,7 @@ "id":"Intezer v2", "reason":"Issue: CIAC-7861", "ignored_native_images":[ - "native:8.4", - "native:8.3", + "native:8.6", "native:candidate" ] }, @@ -171,8 +136,7 @@ "id":"RegexExtractAll", "reason":"Issue: CIAC-6005", "ignored_native_images":[ - "native:8.4", - "native:8.3", + "native:8.6", "native:dev", "native:candidate" ] @@ -181,16 +145,14 @@ "id":"ConvertFile", "reason":"Issue: CIAC-7625", "ignored_native_images":[ - "native:8.4", - "native:8.3" + "native:8.6" ] }, { "id":"DockerHardeningCheck", "reason":"This script is supposed to run inside a container, does not support podman", "ignored_native_images":[ - "native:8.4", - "native:8.3", + "native:8.6", "native:dev", "native:candidate" ] @@ -199,8 +161,7 @@ "id":"Ping", "reason":"see CIAC-8493", "ignored_native_images":[ - "native:8.4", - "native:8.3", + "native:8.6", "native:dev", "native:candidate" ] @@ -208,8 +169,7 @@ ], "flags_versions_mapping":{ "native:dev":"native:dev", - "native:ga":"native:8.4", - "native:maintenance":"native:8.3", + "native:ga":"native:8.6", "native:candidate":"native:candidate" } } From fc03812c5915c2b0b9bea2f56358bd738d9613c2 Mon Sep 17 00:00:00 2001 From: Israel Lappe <79846863+ilappe@users.noreply.github.com> Date: Thu, 22 Feb 2024 14:46:07 +0200 Subject: [PATCH 070/272] ServiceNow mirror: fix bug when mirror not started (#33065) * fix + RN * fix * Update Packs/ServiceNow/ReleaseNotes/2_5_55.md Co-authored-by: Dean Arbel --------- Co-authored-by: Dean Arbel --- .../Integrations/ServiceNowv2/ServiceNowv2.py | 12 +++++++----- Packs/ServiceNow/ReleaseNotes/2_5_55.md | 6 ++++++ Packs/ServiceNow/pack_metadata.json | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 Packs/ServiceNow/ReleaseNotes/2_5_55.md diff --git a/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.py b/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.py index dade0ad6689d..3e64ae867317 100644 --- a/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.py +++ b/Packs/ServiceNow/Integrations/ServiceNowv2/ServiceNowv2.py @@ -2400,7 +2400,7 @@ def get_remote_data_command(client: Client, args: dict[str, Any], params: dict) result = client.get(ticket_type, ticket_id) if not result or 'result' not in result: - return 'Ticket was not found.' + return f'Ticket {ticket_id=} was not found.' if isinstance(result['result'], list): if len(result['result']) == 0: @@ -2417,13 +2417,15 @@ def get_remote_data_command(client: Client, args: dict[str, Any], params: dict) required=False ) - demisto.debug(f'ticket_last_update is {ticket_last_update}') - - if last_update > ticket_last_update: - demisto.debug('Nothing new in the ticket') + demisto.debug(f'ticket_last_update of {ticket_id=} is {ticket_last_update}') + is_fetch = demisto.params().get('isFetch') + if is_fetch and last_update > ticket_last_update: + demisto.debug(f'Nothing new in the ticket {ticket_id=}') ticket = {} else: + # in case we use SNOW just to mirror by setting the incident with mirror fields + # is_fetch will be false, so we will update even the XSOAR incident will be updated then SNOW ticket. demisto.debug(f'ticket is updated: {ticket}') parse_dict_ticket_fields(client, ticket) diff --git a/Packs/ServiceNow/ReleaseNotes/2_5_55.md b/Packs/ServiceNow/ReleaseNotes/2_5_55.md new file mode 100644 index 000000000000..a1ed48d107a9 --- /dev/null +++ b/Packs/ServiceNow/ReleaseNotes/2_5_55.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### ServiceNow v2 + +- Fixed an issue where mirroring did not update fields that were updated before adding the mirroring fields to the incident. \ No newline at end of file diff --git a/Packs/ServiceNow/pack_metadata.json b/Packs/ServiceNow/pack_metadata.json index 876ef3d88ae7..9670be38aec3 100644 --- a/Packs/ServiceNow/pack_metadata.json +++ b/Packs/ServiceNow/pack_metadata.json @@ -2,7 +2,7 @@ "name": "ServiceNow", "description": "Use The ServiceNow IT Service Management (ITSM) solution to modernize the way you manage and deliver services to your users.", "support": "xsoar", - "currentVersion": "2.5.54", + "currentVersion": "2.5.55", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 0322acab5b49289fc3416e662888939918e50e14 Mon Sep 17 00:00:00 2001 From: Michael Yochpaz <8832013+MichaelYochpaz@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:47:23 +0200 Subject: [PATCH 071/272] [OpenCTI] Update Documentation (#33071) * Update README.md * Bump version * ignore `RN112` validation error --- Packs/OpenCTI/.pack-ignore | 3 +++ Packs/OpenCTI/Integrations/OpenCTI/README.md | 6 +++++- Packs/OpenCTI/ReleaseNotes/1_0_10.md | 6 ++++++ Packs/OpenCTI/pack_metadata.json | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 Packs/OpenCTI/ReleaseNotes/1_0_10.md diff --git a/Packs/OpenCTI/.pack-ignore b/Packs/OpenCTI/.pack-ignore index ceea614384b3..a3713be3debe 100644 --- a/Packs/OpenCTI/.pack-ignore +++ b/Packs/OpenCTI/.pack-ignore @@ -1,5 +1,8 @@ [file:README.md] ignore=RM106 +[file:Packs/OpenCTI/ReleaseNotes/1_0_10.md] +ignore=RN112 + [known_words] OpenCTI diff --git a/Packs/OpenCTI/Integrations/OpenCTI/README.md b/Packs/OpenCTI/Integrations/OpenCTI/README.md index e6f0bf8d8a2f..39d0e075ef81 100644 --- a/Packs/OpenCTI/Integrations/OpenCTI/README.md +++ b/Packs/OpenCTI/Integrations/OpenCTI/README.md @@ -1,4 +1,8 @@ -Manages indicators from OpenCTI. Compatible with OpenCTI 4.X API and OpenCTI 5.X API versions. +Manages indicators from OpenCTI. +This integration is compatible with OpenCTI versions from 4.X to 5.11.X. + +**Note**: Due to [breaking changes to the OpenCTI API on version 5.12.0](https://github.com/OpenCTI-Platform/opencti/releases/tag/5.12.0), this integration is not currently compatible with OpenCTI versions 5.12.0 and above. + ## Configure OpenCTI on Cortex XSOAR 1. Navigate to **Settings** > **Integrations** > **Servers & Services**. diff --git a/Packs/OpenCTI/ReleaseNotes/1_0_10.md b/Packs/OpenCTI/ReleaseNotes/1_0_10.md new file mode 100644 index 000000000000..608074fa83b5 --- /dev/null +++ b/Packs/OpenCTI/ReleaseNotes/1_0_10.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### OpenCTI + +- Updated the documentation to specify that versions 5.12.0 and above of OpenCTI are not currently supported due to [breaking changes to the API](https://github.com/OpenCTI-Platform/opencti/releases/tag/5.12.0). diff --git a/Packs/OpenCTI/pack_metadata.json b/Packs/OpenCTI/pack_metadata.json index 62b1957a7cf8..14fd62d7b658 100644 --- a/Packs/OpenCTI/pack_metadata.json +++ b/Packs/OpenCTI/pack_metadata.json @@ -2,7 +2,7 @@ "name": "OpenCTI", "description": "Manages indicators from OpenCTI.", "support": "xsoar", - "currentVersion": "1.0.9", + "currentVersion": "1.0.10", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 179b50e8979ffe3671f0499b4f7b1e281f05e38b Mon Sep 17 00:00:00 2001 From: Adi Bamberger Edri <72088126+BEAdi@users.noreply.github.com> Date: Thu, 22 Feb 2024 18:23:35 +0200 Subject: [PATCH 072/272] Prisma Cloud Compute docs update (#32943) * update README * doc review * RN --- Packs/PrismaCloudCompute/README.md | 205 ++++++++++-------- .../PrismaCloudCompute/ReleaseNotes/1_6_1.md | 5 + Packs/PrismaCloudCompute/pack_metadata.json | 2 +- 3 files changed, 121 insertions(+), 91 deletions(-) create mode 100644 Packs/PrismaCloudCompute/ReleaseNotes/1_6_1.md diff --git a/Packs/PrismaCloudCompute/README.md b/Packs/PrismaCloudCompute/README.md index 1a1f2f682238..9cf86beb422a 100644 --- a/Packs/PrismaCloudCompute/README.md +++ b/Packs/PrismaCloudCompute/README.md @@ -2,79 +2,104 @@ This pack includes Cortex XSIAM content. <~XSIAM> -A step-by-step configuration process is available at Cortex XSIAM Administrator Guide- [Ingest Alerts from Prisma Cloud Compute](https://docs-cortex.paloaltonetworks.com/r/Cortex-XSIAM/Cortex-XSIAM-Administrator-Guide/Ingest-Alerts-from-Prisma-Cloud). - -## Configuration on XSIAM -1. Click **Settings** > **Data Sources**. -2. In the Prisma Cloud Compute Collector configuration, click **Add Instance** to begin a new alerts integration. -3. Specify the name for the Prisma Cloud Compute Collector displayed in Cortex XSIAM. -4. Save & Generate Token. The token is displayed in a blue box, which is blurred in the image below. - * Click the Copy icon next to the Username and Password, and record them in a safe place, as you will need to provide them when you configure the Prisma Cloud Compute Collector for alerts integration. If you forget to record the key and close the window, you will need to generate a new key and repeat this process. When you are finished, click **Done** to close the window. -5. Copy api url. - * In the Data Sources page for the Prisma Cloud Compute Collector that you created, click **Copy api url**, and record it somewhere safe. You will need to provide this API URL when you set the Incoming Webhook URL as part of the configuration in Prisma Cloud Compute. - -**Note**: -The URL format for the tenant is `https://api-.xdr.us.paloaltonetworks.com/logs/v1/prisma`. - -## Configuration on Prisma Cloud Compute -1. In Prisma Cloud Compute, create a webhook as explained in the [Webhook Alerts](https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/alerts/webhook) section of the Prisma Cloud Administrator’s Guide (Compute). - * Config file for Webhook: -```json -//{ - "type": "#type", - "time": "#time", - "container": "#container", - "containerID": "#containerID", - "image": "#image", - "imageID": "#imageID", - "tags": "#tags", - "host": "#host", - "fqdn": "#fqdn", - "function": "#function", - "region": "#region", - "provider": "#provider", - "osRelease": "#osRelease", - "osDistro": "#osDistro", - "runtime": "#runtime", - "appID": "#appID", - "rule": "#rule", - "message": "#message", - "aggregatedAlerts": #aggregatedAlerts, - "dropped": #dropped, - "forensics": "#forensics", - "accountID": "#accountID", - "category": "#category", - "command": "#command", - "startupProcess": "#startupProcess", - "labels": #labels, - "collections": #collections, - "complianceIssues": #complianceIssues, - "vulnerabilities": #vulnerabilities, - "clusters": #clusters, - "namespaces": #namespaces, - "accountIDs": #accountIDs, - "user": "#user" -//} -``` -2. Use the **Webhook** option to configure the webhook. -3. In **Incoming Webhook URL**, paste the API URL that you copied and recorded from **Copy api url**. -4. In **Credential Options**, select **Basic Authentication**, and use the Username and Password that you saved when you generated the token. -5. Select **Container Runtime**. -6. Click **Save**. - * In Cortex XSIAM, once alerts start to come in, a green checkmark appears underneath the Prisma Cloud Compute Collector configuration with the amount of data received. -7. After Cortex XSIAM begins receiving data from Prisma Cloud Compute, you can use XQL Search to search for specific data using the `prisma_cloud_compute_raw` dataset. - - -**Pay Attention**: -Timestamp parsing support is available for the **time** field in `%h %d, %Y %H:%M:%S UTC` format (E.g `Oct 14, 2023 09:16:04 UTC`) +## Overview + +This integration lets you import **Palo Alto Networks - Prisma Cloud Compute** alerts into Cortex XSIAM. + +## Use Cases + +Manage Prisma Cloud Compute alerts in Cortex XSIAM. +You can create new playbooks, or extend the default ones, to analyze alerts, assign tasks based on your analysis, and open tickets on other platforms. + +## Configure Prisma Cloud Compute + +Configure Prisma Cloud Compute to send alerts to Cortex XSIAM by creating an alert profile. + +1. Log in to your Prisma Cloud Compute console. On new Prisma Cloud versions, go to **Runtime Security**. +1. Navigate to **Manage > Alerts**. +1. Create a new alert profile by clicking **Add Profile**. +1. Provide a name, select **Cortex** from the provider list, and select **XSOAR** under Application. +1. Select the alert triggers. Alert triggers specify which alerts are sent to Cortex XSIAM. +1. Click **Save** to save the alert profile. + +## Configure Cortex XSIAM + +1. Navigate to **Settings > Integrations > Instances**. +1. Search for **Prisma Cloud Compute**. +1. Click **Add instance** to create and configure a new integration. + * **Name**: Name for the integration. + * **Fetches incidents**: Configures this integration instance to fetch alerts from Prisma Cloud Compute. + * **Prisma Cloud Compute Console URL**: URL address of your Prisma Cloud Compute console. Copy the address from the alert profile created in Prisma Cloud Compute, or under **Runtime Security** copy the address from **System > Utilities > Path to Console**. + * **Prisma Cloud Compute Project Name (if applies)**: If using projects in Prisma Cloud Compute, enter the project name here. Copy the project name from the alert profile created in Prisma Cloud Compute. + * **Trust any certificate (not secure)**: Skips verification of the CA certificate (not recommended). + * **Use system proxy settings**: Uses the system's proxy settings. + * **Credentials**: Prisma Cloud Compute login credentials. + * **Prisma Cloud Compute CA Certificate**: CA Certificate used by Prisma Cloud Compute. Copy the certificate from the alert profile created in Prisma Cloud Compute. +4. Click **Test** to validate the integration. +5. Click **Done** to save the integration. + + +## Using the integration and scripts + +The integration ships with four default playbooks: +* **Prisma Cloud Compute - Audit Alert v3** +* **Prisma Cloud Compute - Cloud Discovery Alert** +* **Prisma Cloud Compute - Compliance Alert** +* **Prisma Cloud Compute - Vulnerability Alert** + +Three of the above playbooks (all except _Audit Alert v3_) contain a single script. The script in each playbook encode the raw JSON alerts into Cortex XSIAM objects that can then be used in the playbooks. The scripts are: + +* **PrismaCloudComputeParseComplianceAlert** +* **PrismaCloudComputeParseVulnerabilityAlert** +* **PrismaCloudComputeParseCloudDiscoveryAlert** + +To better understand how playbooks and scripts interoperate, consider the _Prisma Cloud Compute - Vulnerability Alert_ playbook. + +* When the playbook is triggered, a task called **Parse Vulnerability Alert** runs. +* The task runs the **PrismaCloudComputeParseVulnerabilityAlert** script, which takes the `prismacloudcomputerawalertjson` field of the incident (the raw JSON alert data) as input. +![image](https://raw.githubusercontent.com/demisto/content/f808c78aa6c94a09450879c8702a1b7f023f1d4b/Packs/PrismaCloudCompute/doc_files/prisma_alert_raw_input.png) + + +* Click **outputs** to see how the script transformed the raw JSON input into a Cortex XSIAM object. + + +![image](https://raw.githubusercontent.com/demisto/content/f808c78aa6c94a09450879c8702a1b7f023f1d4b/Packs/PrismaCloudCompute/doc_files/prisma_alert_outputs.png) + +At this point, you can add tasks that extend the playbook to check and respond to alerts depending on the properties of the Cortex XSIAM object. + +### Audit Alert v3 playbook +This playbook is not similar to the other three playbooks. It is a default playbook for parsing and enrichment of Prisma Cloud Compute audit alerts. + +The playbook has the following sections: + +Enrichment: +- Image details +- Similar container events +- Owner details +- Vulnerabilities +- Compliance details +- Forensics +- Defender logs +Remediation: +- Block Indicators - Generic v3 +- Cloud Response - Generic +- Manual Remediation + +Currently, the playbook supports incidents created by **Runtime** and **WAAS** triggers. + +## Troubleshooting + +If any alerts are missing in Cortex XSIAM, check the status of the integration: + +![image](https://raw.githubusercontent.com/demisto/content/f808c78aa6c94a09450879c8702a1b7f023f1d4b/Packs/PrismaCloudCompute/doc_files/prisma_instance.png) <~XSOAR> ## Overview -This integration lets you import **Palo Alto Networks - Prisma Cloud Compute** alerts into XSOAR +This integration lets you import **Palo Alto Networks - Prisma Cloud Compute** alerts into Cortex XSOAR. ## Use Cases @@ -85,26 +110,26 @@ You can create new playbooks, or extend the default ones, to analyze alerts, ass Configure Prisma Cloud Compute to send alerts to Cortex XSOAR by creating an alert profile. -1. Login to your Prisma Cloud Compute console. +1. Log in to your Prisma Cloud Compute console. On new Prisma Cloud versions, go to **Runtime Security**. 1. Navigate to **Manage > Alerts**. 1. Create a new alert profile by clicking **Add Profile**. -1. On the left, select **XSOAR** from the provider list. -1. On the right, select the alert triggers. Alert triggers specify which alerts are sent to Cortex XSOAR. -1. Click **Save** to save the alert profile +1. Provide a name, select **Cortex** from the provider list, and select **XSOAR** under Application. +1. Select the alert triggers. Alert triggers specify which alerts are sent to Cortex XSOAR. +1. Click **Save** to save the alert profile. ## Configure Cortex XSOAR -1. Navigate to **Settings > Integrations > Servers & Services**. +1. Navigate to **Settings > Integrations > Instances**. 1. Search for **Prisma Cloud Compute**. 1. Click **Add instance** to create and configure a new integration. -* **Name**: Name for the integration. -* **Fetches incidents**: Configures this integration instance to fetch alerts from Prisma Cloud Compute. -* **Prisma Cloud Compute Console URL**: URL address of your Prisma Cloud Compute console. Copy the address from the alert profile created in Prisma Cloud Compute. -* **Prisma Cloud Compute Project Name (if applies)**: If using projects in Prisma Cloud Compute, enter the project name here. Copy the project name from the alert profile created in Prisma Cloud Compute. -* **Trust any certificate (not secure)**: Skips verification of the CA certificate (not recommended). -* **Use system proxy settings**: Uses the system's proxy settings. -* **Credentials**: Prisma Cloud Compute login credentials. -* **Prisma Cloud Compute CA Certificate**: CA Certificate used by Prisma Cloud Compute. Copy the certificate from the alert profile created in Prisma Cloud Compute. + * **Name**: Name for the integration. + * **Fetches incidents**: Configures this integration instance to fetch alerts from Prisma Cloud Compute. + * **Prisma Cloud Compute Console URL**: URL address of your Prisma Cloud Compute console. Copy the address from the alert profile created in Prisma Cloud Compute, or under **Runtime Security** copy the address from **System > Utilities > Path to Console**. + * **Prisma Cloud Compute Project Name (if applies)**: If using projects in Prisma Cloud Compute, enter the project name here. Copy the project name from the alert profile created in Prisma Cloud Compute. + * **Trust any certificate (not secure)**: Skips verification of the CA certificate (not recommended). + * **Use system proxy settings**: Uses the system's proxy settings. + * **Credentials**: Prisma Cloud Compute login credentials. + * **Prisma Cloud Compute CA Certificate**: CA Certificate used by Prisma Cloud Compute. Copy the certificate from the alert profile created in Prisma Cloud Compute. 4. Click **Test** to validate the integration. 5. Click **Done** to save the integration. @@ -112,16 +137,16 @@ Configure Prisma Cloud Compute to send alerts to Cortex XSOAR by creating an ale ## Using the integration and scripts The integration ships with four default playbooks: -* Prisma Cloud Compute - Audit Alert v3 -* Prisma Cloud Compute - Cloud Discovery Alert -* Prisma Cloud Compute - Compliance Alert -* Prisma Cloud Compute - Vulnerability Alert +* **Prisma Cloud Compute - Audit Alert v3** +* **Prisma Cloud Compute - Cloud Discovery Alert** +* **Prisma Cloud Compute - Compliance Alert** +* **Prisma Cloud Compute - Vulnerability Alert** -3 of the above playbooks (all except _Audit Alert v3_) contain a single script. The script in each playbook encode the raw JSON alerts into Cortex XSOAR objects that can then be used in the playbooks. The scripts are: +Three of the above playbooks (all except _Audit Alert v3_) contain a single script. The script in each playbook encode the raw JSON alerts into Cortex XSOAR objects that can then be used in the playbooks. The scripts are: -* PrismaCloudComputeParseComplianceAlert -* PrismaCloudComputeParseVulnerabilityAlert -* PrismaCloudComputeParseCloudDiscoveryAlert +* **PrismaCloudComputeParseComplianceAlert** +* **PrismaCloudComputeParseVulnerabilityAlert** +* **PrismaCloudComputeParseCloudDiscoveryAlert** To better understand how playbooks and scripts interoperate, consider the _Prisma Cloud Compute - Vulnerability Alert_ playbook. @@ -131,7 +156,7 @@ To better understand how playbooks and scripts interoperate, consider the _Prism ![image](https://raw.githubusercontent.com/demisto/content/f808c78aa6c94a09450879c8702a1b7f023f1d4b/Packs/PrismaCloudCompute/doc_files/prisma_alert_raw_input.png) -* Click **outputs** to see how the script transformed the raw JSON input into a XSOAR object. +* Click **outputs** to see how the script transformed the raw JSON input into a Cortex XSOAR object. ![image](https://raw.githubusercontent.com/demisto/content/f808c78aa6c94a09450879c8702a1b7f023f1d4b/Packs/PrismaCloudCompute/doc_files/prisma_alert_outputs.png) @@ -139,7 +164,7 @@ To better understand how playbooks and scripts interoperate, consider the _Prism At this point, you can add tasks that extend the playbook to check and respond to alerts depending on the properties of the Cortex XSOAR object. ### Audit Alert v3 playbook -This playbook is not similar to the other 3 playbooks. It is a default playbook for parsing and enrichment of Prisma Cloud Compute audit alerts. +This playbook is not similar to the other three playbooks. It is a default playbook for parsing and enrichment of Prisma Cloud Compute audit alerts. The playbook has the following sections: @@ -150,7 +175,7 @@ Enrichment: - Vulnerabilities - Compliance details - Forensics -- Defender logs. +- Defender logs Remediation: - Block Indicators - Generic v3 diff --git a/Packs/PrismaCloudCompute/ReleaseNotes/1_6_1.md b/Packs/PrismaCloudCompute/ReleaseNotes/1_6_1.md new file mode 100644 index 000000000000..836a4947a987 --- /dev/null +++ b/Packs/PrismaCloudCompute/ReleaseNotes/1_6_1.md @@ -0,0 +1,5 @@ +#### Integrations + +##### Palo Alto Networks - Prisma Cloud Compute + +Documentation and metadata improvements. \ No newline at end of file diff --git a/Packs/PrismaCloudCompute/pack_metadata.json b/Packs/PrismaCloudCompute/pack_metadata.json index 70e6f4099d14..007dae804f86 100644 --- a/Packs/PrismaCloudCompute/pack_metadata.json +++ b/Packs/PrismaCloudCompute/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Prisma Cloud Compute by Palo Alto Networks", "description": "Use the Prisma Cloud Compute integration to fetch incidents from your Prisma Cloud Compute environment.", "support": "xsoar", - "currentVersion": "1.6.0", + "currentVersion": "1.6.1", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 7f540459515d83697041de072d31fa0ec377c58a Mon Sep 17 00:00:00 2001 From: samuelFain <65926551+samuelFain@users.noreply.github.com> Date: Fri, 23 Feb 2024 03:35:40 +0200 Subject: [PATCH 073/272] [Native Image] Update native image tag (#33080) * Update native image tag * Add supported modules * Remove redundant modules --- Tests/docker_native_image_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/docker_native_image_config.json b/Tests/docker_native_image_config.json index 471cd0dfc482..550e1ae0f836 100644 --- a/Tests/docker_native_image_config.json +++ b/Tests/docker_native_image_config.json @@ -31,7 +31,7 @@ "netutils", "auth-utils" ], - "docker_ref": "demisto/py3-native:8.6.0.88042" + "docker_ref": "demisto/py3-native:8.6.0.88298" }, "native:dev":{ "supported_docker_images":[ From 045cf8cb39c8334dcfbb9030fbcb3332dc2f398e Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 25 Feb 2024 10:36:49 +0200 Subject: [PATCH 074/272] SentinelOne V2 3.2.21 (#33005) (#33057) * Removing the labels and details from incident * Bumped the version * fixed the unit tests * Bumped the docker image * Resolving the RN conflicts --------- Co-authored-by: munna-metron <82433049+munna-metron@users.noreply.github.com> Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> Co-authored-by: merit-maita --- .../Integrations/SentinelOne-V2/SentinelOne-V2.py | 3 --- .../Integrations/SentinelOne-V2/SentinelOne-V2.yml | 2 +- .../SentinelOne-V2/test_data/incidents_2_0.json | 4 ---- .../SentinelOne-V2/test_data/incidents_2_1.json | 8 -------- Packs/SentinelOne/ReleaseNotes/3_2_22.md | 4 ++++ Packs/SentinelOne/pack_metadata.json | 2 +- 6 files changed, 6 insertions(+), 17 deletions(-) create mode 100644 Packs/SentinelOne/ReleaseNotes/3_2_22.md diff --git a/Packs/SentinelOne/Integrations/SentinelOne-V2/SentinelOne-V2.py b/Packs/SentinelOne/Integrations/SentinelOne-V2/SentinelOne-V2.py index 90314079c712..80852daba63a 100644 --- a/Packs/SentinelOne/Integrations/SentinelOne-V2/SentinelOne-V2.py +++ b/Packs/SentinelOne/Integrations/SentinelOne-V2/SentinelOne-V2.py @@ -3483,10 +3483,7 @@ def fetch_handler(client: Client, args): def to_incident(type, data): incident = { - 'details': json.dumps(data), 'rawJSON': json.dumps(data), - 'labels': [{'type': _type, 'value': value if isinstance(value, str) else json.dumps(value)} - for _type, value in data.items()] } if type == 'Threat': diff --git a/Packs/SentinelOne/Integrations/SentinelOne-V2/SentinelOne-V2.yml b/Packs/SentinelOne/Integrations/SentinelOne-V2/SentinelOne-V2.yml index b3de3d701262..608476f1bbfa 100644 --- a/Packs/SentinelOne/Integrations/SentinelOne-V2/SentinelOne-V2.yml +++ b/Packs/SentinelOne/Integrations/SentinelOne-V2/SentinelOne-V2.yml @@ -2385,7 +2385,7 @@ script: - contextPath: SentinelOne.Notes.UpdatedAt description: The note updated time. type: string - dockerimage: demisto/python3:3.10.13.85415 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true ismappable: true isremotesyncin: true diff --git a/Packs/SentinelOne/Integrations/SentinelOne-V2/test_data/incidents_2_0.json b/Packs/SentinelOne/Integrations/SentinelOne-V2/test_data/incidents_2_0.json index 6c45f5082ceb..40e5c1da23ca 100644 --- a/Packs/SentinelOne/Integrations/SentinelOne-V2/test_data/incidents_2_0.json +++ b/Packs/SentinelOne/Integrations/SentinelOne-V2/test_data/incidents_2_0.json @@ -1,15 +1,11 @@ [ { "name": "Sentinel One Threat: Malware", - "labels":[{"type": "accountId", "value": "433241117337583618"}, {"type": "accountName", "value": "SentinelOne"}, {"type": "agentComputerName", "value": "EC2AMAZ-AJ0KANC"}, {"type": "agentDomain", "value": "WORKGROUP"}, {"type": "agentId", "value": "657613730168123595"}, {"type": "agentInfected", "value": "false"}, {"type": "agentIp", "value": "3.122.240.42"}, {"type": "agentIsActive", "value": "false"}, {"type": "agentIsDecommissioned", "value": "true"}, {"type": "agentMachineType", "value": "server"}, {"type": "agentNetworkStatus", "value": "connecting"}, {"type": "agentOsType", "value": "windows"}, {"type": "agentVersion", "value": "3.1.3.38"}, {"type": "annotation", "value": "null"}, {"type": "automaticallyResolved", "value": "false"}, {"type": "browserType", "value": "null"}, {"type": "certId", "value": ""}, {"type": "classification", "value": "Malware"}, {"type": "classificationSource", "value": "Static"}, {"type": "classifierName", "value": "STATIC"}, {"type": "cloudVerdict", "value": "black"}, {"type": "collectionId", "value": "433377870883088367"}, {"type": "commandId", "value": "null"}, {"type": "createdAt", "value": "2019-09-15T12:05:49.095889Z"}, {"type": "createdDate", "value": "2019-09-15T12:05:49.095889Z"}, {"type": "description", "value": "malware detected - not mitigated yet (static engine)"}, {"type": "engines", "value": "[\"reputation\"]"}, {"type": "external_ticket_id", "value": "null"}, {"type": "fileContentHash", "value": "3395856ce81f2b7382dee72602f798b642f14140"}, {"type": "fileCreatedDate", "value": "null"}, {"type": "fileDisplayName", "value": "Unconfirmed 123490.crdownload"}, {"type": "fileExtensionType", "value":"Unknown"}, {"type": "fileIsDotNet", "value": "null"}, {"type":"fileIsExecutable", "value": "false"}, {"type": "fileIsSystem", "value": "false"},{"type": "fileMaliciousContent", "value": "null"}, {"type": "fileObjectId","value": "88FABEEE0F7FE18E"}, {"type": "filePath", "value": "\\Device\\HarddiskVolume1\\Users\\Administrator\\Downloads\\Unconfirmed 123490.crdownload"}, {"type": "fileSha256", "value": "null"}, {"type": "fileVerificationType", "value": "NotSigned"}, {"type": "fromCloud", "value":"false"}, {"type": "fromScan", "value": "false"}, {"type": "id", "value":"715718962991148224"}, {"type": "indicators", "value": "[]"}, {"type":"initiatedBy", "value": "agentPolicy"}, {"type": "initiatedByDescription","value": "Agent Policy"}, {"type": "initiatingUserId", "value": "null"}, {"type":"isCertValid", "value": "false"}, {"type": "isInteractiveSession", "value":"false"}, {"type": "isPartialStory", "value": "false"}, {"type":"maliciousGroupId", "value": "A8F6CB4CB9AE09A1"}, {"type":"maliciousProcessArguments", "value": "null"}, {"type": "markedAsBenign", "value":"false"}, {"type": "mitigationMode", "value": "protect"}, {"type": "mitigationReport", "value": "{\"kill\": {\"status\": \"success\"}, \"network_quarantine\": {\"status\": null}, \"quarantine\": {\"status\": \"success\"}, \"remediate\": {\"status\": null}, \"rollback\": {\"status\": null}, \"unquarantine\": {\"status\": null}}"}, {"type": "mitigationStatus", "value": "mitigated"}, {"type": "publisher", "value": ""}, {"type": "rank", "value": "7"}, {"type": "resolved","value": "true"}, {"type": "siteId", "value": "475482421366727779"}, {"type": "siteName", "value": "demisto"}, {"type": "threatAgentVersion", "value":"3.1.3.38"}, {"type": "threatName", "value": "Unconfirmed 123490.crdownload"}, {"type": "updatedAt", "value": "2020-04-02T14:52:28.528753Z"}, {"type":"username", "value": "EC2AMAZ-AJ0KANC\\Administrator"}, {"type":"whiteningOptions", "value": "[\"hash\"]"}, {"type": "mirror_direction", "value": "null"}, {"type": "mirror_instance", "value": ""}, {"type": "incident_type", "value": "SentinelOne Incident"}], - "details": "{\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIp\": \"3.122.240.42\", \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentNetworkStatus\": \"connecting\", \"agentOsType\": \"windows\", \"agentVersion\": \"3.1.3.38\", \"annotation\": null, \"automaticallyResolved\": false, \"browserType\": null, \"certId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"classifierName\": \"STATIC\", \"cloudVerdict\": \"black\", \"collectionId\": \"433377870883088367\", \"commandId\": null, \"createdAt\": \"2019-09-15T12:05:49.095889Z\", \"createdDate\": \"2019-09-15T12:05:49.095889Z\", \"description\": \"malware detected - not mitigated yet (static engine)\", \"engines\": [\"reputation\"], \"external_ticket_id\": null, \"fileContentHash\": \"3395856ce81f2b7382dee72602f798b642f14140\", \"fileCreatedDate\": null, \"fileDisplayName\": \"Unconfirmed 123490.crdownload\", \"fileExtensionType\": \"Unknown\", \"fileIsDotNet\": null, \"fileIsExecutable\": false, \"fileIsSystem\": false, \"fileMaliciousContent\": null, \"fileObjectId\": \"88FABEEE0F7FE18E\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Unconfirmed 123490.crdownload\", \"fileSha256\": null, \"fileVerificationType\": \"NotSigned\", \"fromCloud\": false, \"fromScan\": false, \"id\": \"715718962991148224\", \"indicators\": [], \"initiatedBy\": \"agentPolicy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"isCertValid\": false, \"isInteractiveSession\": false, \"isPartialStory\": false, \"maliciousGroupId\": \"A8F6CB4CB9AE09A1\", \"maliciousProcessArguments\": null, \"markedAsBenign\": false, \"mitigationMode\": \"protect\", \"mitigationReport\": {\"kill\": {\"status\": \"success\"}, \"network_quarantine\": {\"status\": null}, \"quarantine\": {\"status\": \"success\"}, \"remediate\": {\"status\": null}, \"rollback\": {\"status\": null}, \"unquarantine\": {\"status\": null}}, \"mitigationStatus\": \"mitigated\", \"publisher\": \"\", \"rank\": 7, \"resolved\": true, \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"threatAgentVersion\": \"3.1.3.38\", \"threatName\": \"Unconfirmed 123490.crdownload\", \"updatedAt\": \"2020-04-02T14:52:28.528753Z\", \"username\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"whiteningOptions\": [\"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}", "occurred": "2019-09-15T12:05:49.095889Z", "rawJSON": "{\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIp\": \"3.122.240.42\", \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentNetworkStatus\": \"connecting\", \"agentOsType\": \"windows\", \"agentVersion\": \"3.1.3.38\", \"annotation\": null, \"automaticallyResolved\": false, \"browserType\": null, \"certId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"classifierName\": \"STATIC\", \"cloudVerdict\": \"black\", \"collectionId\": \"433377870883088367\", \"commandId\": null, \"createdAt\": \"2019-09-15T12:05:49.095889Z\", \"createdDate\": \"2019-09-15T12:05:49.095889Z\", \"description\": \"malware detected - not mitigated yet (static engine)\", \"engines\": [\"reputation\"], \"external_ticket_id\": null, \"fileContentHash\": \"3395856ce81f2b7382dee72602f798b642f14140\", \"fileCreatedDate\": null, \"fileDisplayName\": \"Unconfirmed 123490.crdownload\", \"fileExtensionType\": \"Unknown\", \"fileIsDotNet\": null, \"fileIsExecutable\": false, \"fileIsSystem\": false, \"fileMaliciousContent\": null, \"fileObjectId\": \"88FABEEE0F7FE18E\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Unconfirmed 123490.crdownload\", \"fileSha256\": null, \"fileVerificationType\": \"NotSigned\", \"fromCloud\": false, \"fromScan\": false, \"id\": \"715718962991148224\", \"indicators\": [], \"initiatedBy\": \"agentPolicy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"isCertValid\": false, \"isInteractiveSession\": false, \"isPartialStory\": false, \"maliciousGroupId\": \"A8F6CB4CB9AE09A1\", \"maliciousProcessArguments\": null, \"markedAsBenign\": false, \"mitigationMode\": \"protect\", \"mitigationReport\": {\"kill\": {\"status\": \"success\"}, \"network_quarantine\": {\"status\": null}, \"quarantine\": {\"status\": \"success\"}, \"remediate\": {\"status\": null}, \"rollback\": {\"status\": null}, \"unquarantine\": {\"status\": null}}, \"mitigationStatus\": \"mitigated\", \"publisher\": \"\", \"rank\": 7, \"resolved\": true, \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"threatAgentVersion\": \"3.1.3.38\", \"threatName\": \"Unconfirmed 123490.crdownload\", \"updatedAt\": \"2020-04-02T14:52:28.528753Z\", \"username\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"whiteningOptions\": [\"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}" }, { "name": "Sentinel One Threat: Malware", - "labels": [{"type": "accountId", "value": "43324111733712345"}, {"type": "accountName", "value": "SentinelOne"}, {"type": "agentComputerName", "value": "EC2AMAZ-AJ0KANC"}, {"type": "agentDomain", "value": "WORKGROUP"}, {"type": "agentId", "value": "657613730168123595"}, {"type": "agentInfected", "value": "false"}, {"type": "agentIp", "value": "3.122.240.42"}, {"type": "agentIsActive", "value": "false"}, {"type": "agentIsDecommissioned", "value": "true"}, {"type": "agentMachineType", "value": "server"}, {"type": "agentNetworkStatus", "value": "connecting"}, {"type": "agentOsType", "value": "windows"}, {"type": "agentVersion", "value": "3.1.3.38"}, {"type": "annotation", "value": "null"}, {"type": "automaticallyResolved", "value": "false"}, {"type": "browserType", "value": "null"}, {"type": "certId", "value": ""}, {"type": "classification", "value": "Malware"}, {"type": "classificationSource", "value": "Static"}, {"type": "classifierName", "value": "STATIC"}, {"type": "cloudVerdict", "value": "black"}, {"type": "collectionId", "value": "433377870883088367"}, {"type": "commandId", "value": "null"}, {"type": "createdAt", "value": "2019-09-15T12:14:42.440985Z"}, {"type": "createdDate", "value": "2019-09-15T12:14:42.440985Z"}, {"type": "description", "value": "malware detected - not mitigated yet (static engine)"}, {"type": "engines", "value": "[\"reputation\"]"}, {"type": "external_ticket_id", "value": "null"}, {"type": "fileContentHash", "value": "3395856ce81f2b7382dee72602f798b642f14140"}, {"type": "fileCreatedDate", "value": "null"}, {"type": "fileDisplayName", "value": "Unconfirmed 123490.crdownload"}, {"type": "fileExtensionType", "value":"Unknown"}, {"type": "fileIsDotNet", "value": "null"}, {"type":"fileIsExecutable", "value": "false"}, {"type": "fileIsSystem", "value": "false"},{"type": "fileMaliciousContent", "value": "null"}, {"type": "fileObjectId","value": "88FABEEE0F7FE18E"}, {"type": "filePath", "value": "\\Device\\HarddiskVolume1\\Users\\Administrator\\Downloads\\Unconfirmed 123490.crdownload"}, {"type": "fileSha256", "value": "null"}, {"type": "fileVerificationType", "value": "NotSigned"}, {"type": "fromCloud", "value":"false"}, {"type": "fromScan", "value": "false"}, {"type": "id", "value":"1234518962991148224"}, {"type": "indicators", "value": "[]"}, {"type":"initiatedBy", "value": "agentPolicy"}, {"type": "initiatedByDescription","value": "Agent Policy"}, {"type": "initiatingUserId", "value": "null"}, {"type":"isCertValid", "value": "false"}, {"type": "isInteractiveSession", "value":"false"}, {"type": "isPartialStory", "value": "false"}, {"type":"maliciousGroupId", "value": "A8F6CB4CB9AE09A1"}, {"type":"maliciousProcessArguments", "value": "null"}, {"type": "markedAsBenign", "value":"false"}, {"type": "mitigationMode", "value": "protect"}, {"type": "mitigationReport", "value": "{\"kill\": {\"status\": \"success\"}, \"network_quarantine\": {\"status\": null}, \"quarantine\": {\"status\": \"success\"}, \"remediate\": {\"status\": null}, \"rollback\": {\"status\": null}, \"unquarantine\": {\"status\": null}}"}, {"type": "mitigationStatus", "value": "mitigated"}, {"type": "publisher", "value": ""}, {"type": "rank", "value": "4"}, {"type": "resolved","value": "true"}, {"type": "siteId", "value": "475482421366727779"}, {"type": "siteName", "value": "demisto"}, {"type": "threatAgentVersion", "value":"3.1.3.38"}, {"type": "threatName", "value": "Unconfirmed 123490.crdownload"}, {"type": "updatedAt", "value": "2020-04-02T14:52:28.528753Z"}, {"type":"username", "value": "EC2AMAZ-AJ0KANC\\Administrator"}, {"type":"whiteningOptions", "value": "[\"hash\"]"}, {"type": "mirror_direction", "value": "null"}, {"type": "mirror_instance", "value": ""}, {"type": "incident_type", "value": "SentinelOne Incident"}], - "details": "{\"accountId\": \"43324111733712345\", \"accountName\": \"SentinelOne\", \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIp\": \"3.122.240.42\", \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentNetworkStatus\": \"connecting\", \"agentOsType\": \"windows\", \"agentVersion\": \"3.1.3.38\", \"annotation\": null, \"automaticallyResolved\": false, \"browserType\": null, \"certId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"classifierName\": \"STATIC\", \"cloudVerdict\": \"black\", \"collectionId\": \"433377870883088367\", \"commandId\": null, \"createdAt\": \"2019-09-15T12:14:42.440985Z\", \"createdDate\": \"2019-09-15T12:14:42.440985Z\", \"description\": \"malware detected - not mitigated yet (static engine)\", \"engines\": [\"reputation\"], \"external_ticket_id\": null, \"fileContentHash\": \"3395856ce81f2b7382dee72602f798b642f14140\", \"fileCreatedDate\": null, \"fileDisplayName\": \"Unconfirmed 123490.crdownload\", \"fileExtensionType\": \"Unknown\", \"fileIsDotNet\": null, \"fileIsExecutable\": false, \"fileIsSystem\": false, \"fileMaliciousContent\": null, \"fileObjectId\": \"88FABEEE0F7FE18E\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Unconfirmed 123490.crdownload\", \"fileSha256\": null, \"fileVerificationType\": \"NotSigned\", \"fromCloud\": false, \"fromScan\": false, \"id\": \"1234518962991148224\", \"indicators\": [], \"initiatedBy\": \"agentPolicy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"isCertValid\": false, \"isInteractiveSession\": false, \"isPartialStory\": false, \"maliciousGroupId\": \"A8F6CB4CB9AE09A1\", \"maliciousProcessArguments\": null, \"markedAsBenign\": false, \"mitigationMode\": \"protect\", \"mitigationReport\": {\"kill\": {\"status\": \"success\"}, \"network_quarantine\": {\"status\": null}, \"quarantine\": {\"status\": \"success\"}, \"remediate\": {\"status\": null}, \"rollback\": {\"status\": null}, \"unquarantine\": {\"status\": null}}, \"mitigationStatus\": \"mitigated\", \"publisher\": \"\", \"rank\": 4, \"resolved\": true, \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"threatAgentVersion\": \"3.1.3.38\", \"threatName\": \"Unconfirmed 123490.crdownload\", \"updatedAt\": \"2020-04-02T14:52:28.528753Z\", \"username\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"whiteningOptions\": [\"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}", "occurred": "2019-09-15T12:14:42.440985Z", "rawJSON": "{\"accountId\": \"43324111733712345\", \"accountName\": \"SentinelOne\", \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIp\": \"3.122.240.42\", \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentNetworkStatus\": \"connecting\", \"agentOsType\": \"windows\", \"agentVersion\": \"3.1.3.38\", \"annotation\": null, \"automaticallyResolved\": false, \"browserType\": null, \"certId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"classifierName\": \"STATIC\", \"cloudVerdict\": \"black\", \"collectionId\": \"433377870883088367\", \"commandId\": null, \"createdAt\": \"2019-09-15T12:14:42.440985Z\", \"createdDate\": \"2019-09-15T12:14:42.440985Z\", \"description\": \"malware detected - not mitigated yet (static engine)\", \"engines\": [\"reputation\"], \"external_ticket_id\": null, \"fileContentHash\": \"3395856ce81f2b7382dee72602f798b642f14140\", \"fileCreatedDate\": null, \"fileDisplayName\": \"Unconfirmed 123490.crdownload\", \"fileExtensionType\": \"Unknown\", \"fileIsDotNet\": null, \"fileIsExecutable\": false, \"fileIsSystem\": false, \"fileMaliciousContent\": null, \"fileObjectId\": \"88FABEEE0F7FE18E\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Unconfirmed 123490.crdownload\", \"fileSha256\": null, \"fileVerificationType\": \"NotSigned\", \"fromCloud\": false, \"fromScan\": false, \"id\": \"1234518962991148224\", \"indicators\": [], \"initiatedBy\": \"agentPolicy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"isCertValid\": false, \"isInteractiveSession\": false, \"isPartialStory\": false, \"maliciousGroupId\": \"A8F6CB4CB9AE09A1\", \"maliciousProcessArguments\": null, \"markedAsBenign\": false, \"mitigationMode\": \"protect\", \"mitigationReport\": {\"kill\": {\"status\": \"success\"}, \"network_quarantine\": {\"status\": null}, \"quarantine\": {\"status\": \"success\"}, \"remediate\": {\"status\": null}, \"rollback\": {\"status\": null}, \"unquarantine\": {\"status\": null}}, \"mitigationStatus\": \"mitigated\", \"publisher\": \"\", \"rank\": 4, \"resolved\": true, \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"threatAgentVersion\": \"3.1.3.38\", \"threatName\": \"Unconfirmed 123490.crdownload\", \"updatedAt\": \"2020-04-02T14:52:28.528753Z\", \"username\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"whiteningOptions\": [\"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}" } diff --git a/Packs/SentinelOne/Integrations/SentinelOne-V2/test_data/incidents_2_1.json b/Packs/SentinelOne/Integrations/SentinelOne-V2/test_data/incidents_2_1.json index 1f82fac5ad38..d77f58b9f266 100644 --- a/Packs/SentinelOne/Integrations/SentinelOne-V2/test_data/incidents_2_1.json +++ b/Packs/SentinelOne/Integrations/SentinelOne-V2/test_data/incidents_2_1.json @@ -1,29 +1,21 @@ [ { "name": "Sentinel One Threat: Malware", - "labels": [{"type": "agentDetectionInfo", "value": "{\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}"}, {"type": "agentRealtimeInfo", "value": "{\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}"}, {"type": "containerInfo", "value": "{\"id\": null, \"image\": null, \"labels\": null, \"name\": null}"}, {"type": "id", "value": "715718962991148224"}, {"type": "indicators", "value": "[]"}, {"type": "kubernetesInfo", "value": "{\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}"}, {"type": "mitigationStatus", "value": "[{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:05:49.228950Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:05:49.339327Z\", \"latestReport\": null, \"status\": \"success\"}]"}, {"type": "threatInfo", "value": "{\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"black\", \"collectionId\": \"433377870883088367\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:05:49.095889Z\", \"detectionType\": \"static\", \"engines\": [\"Reputation\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"CRDOWNLOAD\", \"fileExtensionType\": \"Unknown\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Unconfirmed 123490.crdownload\", \"fileSize\": 0, \"fileVerificationType\": \"NotSigned\", \"identifiedAt\": \"2019-09-15T12:05:49.009000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": false, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"publisherName\": \"\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"3395856ce81f2b7382dee72602f798b642f14140\", \"sha256\": null, \"storyline\": \"A8F6CB4CB9AE09A1\", \"threatId\": \"715718962991148224\", \"threatName\": \"Unconfirmed 123490.crdownload\", \"updatedAt\": \"2020-04-02T14:52:28.528753Z\"}"}, {"type": "whiteningOptions", "value": "[\"hash\"]"}, {"type": "mirror_direction", "value": "null"}, {"type": "mirror_instance", "value": ""}, {"type": "incident_type", "value": "SentinelOne Incident"}], - "details": "{\"agentDetectionInfo\": {\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}, \"agentRealtimeInfo\": {\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}, \"containerInfo\": {\"id\": null, \"image\": null, \"labels\": null, \"name\": null}, \"id\": \"715718962991148224\", \"indicators\": [], \"kubernetesInfo\": {\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}, \"mitigationStatus\": [{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:05:49.228950Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:05:49.339327Z\", \"latestReport\": null, \"status\": \"success\"}], \"threatInfo\": {\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"black\", \"collectionId\": \"433377870883088367\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:05:49.095889Z\", \"detectionType\": \"static\", \"engines\": [\"Reputation\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"CRDOWNLOAD\", \"fileExtensionType\": \"Unknown\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Unconfirmed 123490.crdownload\", \"fileSize\": 0, \"fileVerificationType\": \"NotSigned\", \"identifiedAt\": \"2019-09-15T12:05:49.009000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": false, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"publisherName\": \"\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"3395856ce81f2b7382dee72602f798b642f14140\", \"sha256\": null, \"storyline\": \"A8F6CB4CB9AE09A1\", \"threatId\": \"715718962991148224\", \"threatName\": \"Unconfirmed 123490.crdownload\", \"updatedAt\": \"2020-04-02T14:52:28.528753Z\"}, \"whiteningOptions\": [\"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}", "occurred": "2019-09-15T12:05:49.095889Z", "rawJSON": "{\"agentDetectionInfo\": {\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}, \"agentRealtimeInfo\": {\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}, \"containerInfo\": {\"id\": null, \"image\": null, \"labels\": null, \"name\": null}, \"id\": \"715718962991148224\", \"indicators\": [], \"kubernetesInfo\": {\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}, \"mitigationStatus\": [{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:05:49.228950Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:05:49.339327Z\", \"latestReport\": null, \"status\": \"success\"}], \"threatInfo\": {\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"black\", \"collectionId\": \"433377870883088367\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:05:49.095889Z\", \"detectionType\": \"static\", \"engines\": [\"Reputation\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"CRDOWNLOAD\", \"fileExtensionType\": \"Unknown\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Unconfirmed 123490.crdownload\", \"fileSize\": 0, \"fileVerificationType\": \"NotSigned\", \"identifiedAt\": \"2019-09-15T12:05:49.009000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": false, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"publisherName\": \"\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"3395856ce81f2b7382dee72602f798b642f14140\", \"sha256\": null, \"storyline\": \"A8F6CB4CB9AE09A1\", \"threatId\": \"715718962991148224\", \"threatName\": \"Unconfirmed 123490.crdownload\", \"updatedAt\": \"2020-04-02T14:52:28.528753Z\"}, \"whiteningOptions\": [\"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}" }, { "name": "Sentinel One Threat: Malware", - "labels": [{"type": "agentDetectionInfo", "value": "{\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}"}, {"type": "agentRealtimeInfo", "value": "{\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}"}, {"type": "containerInfo", "value": "{\"id\": null, \"image\": null, \"labels\": null, \"name\": null}"}, {"type": "id", "value": "715723437013282014"}, {"type": "indicators", "value": "[{\"category\": \"General\", \"description\": \"This is an AutoIT script compiled to an exe file.\", \"ids\": [25], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports functions used to raise kernel exceptions.\", \"ids\": [24], \"tactics\": []}, {\"category\": \"InfoStealer\", \"description\": \"This binary has keylogging capabilities.\", \"ids\": [23], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports debugger functions.\", \"ids\": [6], \"tactics\": []}]"}, {"type": "kubernetesInfo", "value": "{\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}"}, {"type": "mitigationStatus", "value": "[{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:42.631216Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:42.977017Z\", \"latestReport\": null, \"status\": \"success\"}]"}, {"type": "threatInfo", "value": "{\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"CHIP DIGITAL GMBH\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"provider_unknown\", \"collectionId\": \"715723437055225055\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:14:42.440985Z\", \"detectionType\": \"static\", \"engines\": [\"On-Write DFI\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"EXE\", \"fileExtensionType\": \"Executable\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Ncat Netcat Portable - CHIP-Installer.exe\", \"fileSize\": 0, \"fileVerificationType\": \"SignedVerified\", \"identifiedAt\": \"2019-09-15T12:14:41.260000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": true, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"publisherName\": \"CHIP DIGITAL GMBH\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"d8757a0396d05a1d532422827a70a7966c361366\", \"sha256\": null, \"storyline\": \"8BF4207AFA583317\", \"threatId\": \"715723437013282014\", \"threatName\": \"Ncat Netcat Portable - CHIP-Installer.exe\", \"updatedAt\": \"2020-04-02T14:52:28.534110Z\"}"}, {"type": "whiteningOptions", "value": "[\"path\", \"certificate\", \"hash\"]"}, {"type": "mirror_direction", "value": "null"}, {"type": "mirror_instance", "value": ""}, {"type": "incident_type", "value": "SentinelOne Incident"}], - "details": "{\"agentDetectionInfo\": {\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}, \"agentRealtimeInfo\": {\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}, \"containerInfo\": {\"id\": null, \"image\": null, \"labels\": null, \"name\": null}, \"id\": \"715723437013282014\", \"indicators\": [{\"category\": \"General\", \"description\": \"This is an AutoIT script compiled to an exe file.\", \"ids\": [25], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports functions used to raise kernel exceptions.\", \"ids\": [24], \"tactics\": []}, {\"category\": \"InfoStealer\", \"description\": \"This binary has keylogging capabilities.\", \"ids\": [23], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports debugger functions.\", \"ids\": [6], \"tactics\": []}], \"kubernetesInfo\": {\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}, \"mitigationStatus\": [{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:42.631216Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:42.977017Z\", \"latestReport\": null, \"status\": \"success\"}], \"threatInfo\": {\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"CHIP DIGITAL GMBH\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"provider_unknown\", \"collectionId\": \"715723437055225055\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:14:42.440985Z\", \"detectionType\": \"static\", \"engines\": [\"On-Write DFI\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"EXE\", \"fileExtensionType\": \"Executable\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Ncat Netcat Portable - CHIP-Installer.exe\", \"fileSize\": 0, \"fileVerificationType\": \"SignedVerified\", \"identifiedAt\": \"2019-09-15T12:14:41.260000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": true, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"publisherName\": \"CHIP DIGITAL GMBH\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"d8757a0396d05a1d532422827a70a7966c361366\", \"sha256\": null, \"storyline\": \"8BF4207AFA583317\", \"threatId\": \"715723437013282014\", \"threatName\": \"Ncat Netcat Portable - CHIP-Installer.exe\", \"updatedAt\": \"2020-04-02T14:52:28.534110Z\"}, \"whiteningOptions\": [\"path\", \"certificate\", \"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}", "occurred": "2019-09-15T12:14:42.440985Z", "rawJSON": "{\"agentDetectionInfo\": {\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}, \"agentRealtimeInfo\": {\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}, \"containerInfo\": {\"id\": null, \"image\": null, \"labels\": null, \"name\": null}, \"id\": \"715723437013282014\", \"indicators\": [{\"category\": \"General\", \"description\": \"This is an AutoIT script compiled to an exe file.\", \"ids\": [25], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports functions used to raise kernel exceptions.\", \"ids\": [24], \"tactics\": []}, {\"category\": \"InfoStealer\", \"description\": \"This binary has keylogging capabilities.\", \"ids\": [23], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports debugger functions.\", \"ids\": [6], \"tactics\": []}], \"kubernetesInfo\": {\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}, \"mitigationStatus\": [{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:42.631216Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:42.977017Z\", \"latestReport\": null, \"status\": \"success\"}], \"threatInfo\": {\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"CHIP DIGITAL GMBH\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"provider_unknown\", \"collectionId\": \"715723437055225055\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:14:42.440985Z\", \"detectionType\": \"static\", \"engines\": [\"On-Write DFI\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"EXE\", \"fileExtensionType\": \"Executable\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Ncat Netcat Portable - CHIP-Installer.exe\", \"fileSize\": 0, \"fileVerificationType\": \"SignedVerified\", \"identifiedAt\": \"2019-09-15T12:14:41.260000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": true, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"publisherName\": \"CHIP DIGITAL GMBH\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"d8757a0396d05a1d532422827a70a7966c361366\", \"sha256\": null, \"storyline\": \"8BF4207AFA583317\", \"threatId\": \"715723437013282014\", \"threatName\": \"Ncat Netcat Portable - CHIP-Installer.exe\", \"updatedAt\": \"2020-04-02T14:52:28.534110Z\"}, \"whiteningOptions\": [\"path\", \"certificate\", \"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}" }, { "name": "Sentinel One Threat: Malware", - "labels": [{"type": "agentDetectionInfo", "value": "{\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}"}, {"type": "agentRealtimeInfo", "value": "{\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}"}, {"type": "containerInfo", "value": "{\"id\": null, \"image\": null, \"labels\": null, \"name\": null}"}, {"type": "id", "value": "715723444638526700"}, {"type": "indicators", "value": "[{\"category\": \"General\", \"description\": \"This is an AutoIT script compiled to an exe file.\", \"ids\": [25], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports functions used to raise kernel exceptions.\", \"ids\": [24], \"tactics\": []}, {\"category\": \"InfoStealer\", \"description\": \"This binary has keylogging capabilities.\", \"ids\": [23], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports debugger functions.\", \"ids\": [6], \"tactics\": []}]"}, {"type": "kubernetesInfo", "value": "{\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}"}, {"type": "mitigationStatus", "value": "[{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:43.507091Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:43.787095Z\", \"latestReport\": null, \"status\": \"success\"}]"}, {"type": "threatInfo", "value": "{\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"provider_unknown\", \"collectionId\": \"715723437055225055\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:14:43.349807Z\", \"detectionType\": \"static\", \"engines\": [\"On-Write DFI\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"EXE\", \"fileExtensionType\": \"Executable\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Ncat Netcat Portable - CHIP-Installer.exe\", \"fileSize\": 0, \"fileVerificationType\": \"PathNotFound\", \"identifiedAt\": \"2019-09-15T12:14:41.620000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": false, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"\", \"publisherName\": \"\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"d8757a0396d05a1d532422827a70a7966c361366\", \"sha256\": null, \"storyline\": \"3E41618589D5CB3E\", \"threatId\": \"715723444638526700\", \"threatName\": \"Ncat Netcat Portable - CHIP-Installer.exe\", \"updatedAt\": \"2020-04-02T14:52:28.535860Z\"}"}, {"type": "whiteningOptions", "value": "[\"path\", \"hash\"]"}, {"type": "mirror_direction", "value": "null"}, {"type": "mirror_instance", "value": ""}, {"type": "incident_type", "value": "SentinelOne Incident"}], - "details": "{\"agentDetectionInfo\": {\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}, \"agentRealtimeInfo\": {\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}, \"containerInfo\": {\"id\": null, \"image\": null, \"labels\": null, \"name\": null}, \"id\": \"715723444638526700\", \"indicators\": [{\"category\": \"General\", \"description\": \"This is an AutoIT script compiled to an exe file.\", \"ids\": [25], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports functions used to raise kernel exceptions.\", \"ids\": [24], \"tactics\": []}, {\"category\": \"InfoStealer\", \"description\": \"This binary has keylogging capabilities.\", \"ids\": [23], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports debugger functions.\", \"ids\": [6], \"tactics\": []}], \"kubernetesInfo\": {\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}, \"mitigationStatus\": [{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:43.507091Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:43.787095Z\", \"latestReport\": null, \"status\": \"success\"}], \"threatInfo\": {\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"provider_unknown\", \"collectionId\": \"715723437055225055\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:14:43.349807Z\", \"detectionType\": \"static\", \"engines\": [\"On-Write DFI\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"EXE\", \"fileExtensionType\": \"Executable\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Ncat Netcat Portable - CHIP-Installer.exe\", \"fileSize\": 0, \"fileVerificationType\": \"PathNotFound\", \"identifiedAt\": \"2019-09-15T12:14:41.620000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": false, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"\", \"publisherName\": \"\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"d8757a0396d05a1d532422827a70a7966c361366\", \"sha256\": null, \"storyline\": \"3E41618589D5CB3E\", \"threatId\": \"715723444638526700\", \"threatName\": \"Ncat Netcat Portable - CHIP-Installer.exe\", \"updatedAt\": \"2020-04-02T14:52:28.535860Z\"}, \"whiteningOptions\": [\"path\", \"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}", "occurred": "2019-09-15T12:14:43.349807Z", "rawJSON": "{\"agentDetectionInfo\": {\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}, \"agentRealtimeInfo\": {\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}, \"containerInfo\": {\"id\": null, \"image\": null, \"labels\": null, \"name\": null}, \"id\": \"715723444638526700\", \"indicators\": [{\"category\": \"General\", \"description\": \"This is an AutoIT script compiled to an exe file.\", \"ids\": [25], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports functions used to raise kernel exceptions.\", \"ids\": [24], \"tactics\": []}, {\"category\": \"InfoStealer\", \"description\": \"This binary has keylogging capabilities.\", \"ids\": [23], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports debugger functions.\", \"ids\": [6], \"tactics\": []}], \"kubernetesInfo\": {\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}, \"mitigationStatus\": [{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:43.507091Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:43.787095Z\", \"latestReport\": null, \"status\": \"success\"}], \"threatInfo\": {\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"provider_unknown\", \"collectionId\": \"715723437055225055\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:14:43.349807Z\", \"detectionType\": \"static\", \"engines\": [\"On-Write DFI\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"EXE\", \"fileExtensionType\": \"Executable\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Ncat Netcat Portable - CHIP-Installer.exe\", \"fileSize\": 0, \"fileVerificationType\": \"PathNotFound\", \"identifiedAt\": \"2019-09-15T12:14:41.620000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": false, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"\", \"publisherName\": \"\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"d8757a0396d05a1d532422827a70a7966c361366\", \"sha256\": null, \"storyline\": \"3E41618589D5CB3E\", \"threatId\": \"715723444638526700\", \"threatName\": \"Ncat Netcat Portable - CHIP-Installer.exe\", \"updatedAt\": \"2020-04-02T14:52:28.535860Z\"}, \"whiteningOptions\": [\"path\", \"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}" }, { "name": "Sentinel One Threat: Malware", - "labels": [{"type": "agentDetectionInfo", "value": "{\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}"}, {"type": "agentRealtimeInfo", "value": "{\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}"}, {"type": "containerInfo", "value": "{\"id\": null, \"image\": null, \"labels\": null, \"name\": null}"}, {"type": "id", "value": "715723450678324472"}, {"type": "indicators", "value": "[{\"category\": \"General\", \"description\": \"This is an AutoIT script compiled to an exe file.\", \"ids\": [25], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports functions used to raise kernel exceptions.\", \"ids\": [24], \"tactics\": []}, {\"category\": \"InfoStealer\", \"description\": \"This binary has keylogging capabilities.\", \"ids\": [23], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports debugger functions.\", \"ids\": [6], \"tactics\": []}]"}, {"type": "kubernetesInfo", "value": "{\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}"}, {"type": "mitigationStatus", "value": "[{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:44.336124Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:44.469734Z\", \"latestReport\": null, \"status\": \"success\"}]"}, {"type": "threatInfo", "value": "{\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"CHIP DIGITAL GMBH\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"provider_unknown\", \"collectionId\": \"715723450695101689\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:14:44.069617Z\", \"detectionType\": \"static\", \"engines\": [\"On-Write DFI\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"EXE\", \"fileExtensionType\": \"Executable\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Ncat Netcat Portable - CHIP-Installer (1).exe\", \"fileSize\": 0, \"fileVerificationType\": \"SignedVerified\", \"identifiedAt\": \"2019-09-15T12:14:43.215000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": true, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"publisherName\": \"CHIP DIGITAL GMBH\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"ccce727e39cb8d955a323bf2c0419f31fb917e5a\", \"sha256\": null, \"storyline\": \"5F18360CAB4D45B7\", \"threatId\": \"715723450678324472\", \"threatName\": \"Ncat Netcat Portable - CHIP-Installer (1).exe\", \"updatedAt\": \"2020-04-02T14:52:28.537685Z\"}"}, {"type": "whiteningOptions", "value": "[\"path\", \"certificate\", \"hash\"]"}, {"type": "mirror_direction", "value": "null"}, {"type": "mirror_instance", "value": ""}, {"type": "incident_type", "value": "SentinelOne Incident"}], - "details": "{\"agentDetectionInfo\": {\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}, \"agentRealtimeInfo\": {\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}, \"containerInfo\": {\"id\": null, \"image\": null, \"labels\": null, \"name\": null}, \"id\": \"715723450678324472\", \"indicators\": [{\"category\": \"General\", \"description\": \"This is an AutoIT script compiled to an exe file.\", \"ids\": [25], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports functions used to raise kernel exceptions.\", \"ids\": [24], \"tactics\": []}, {\"category\": \"InfoStealer\", \"description\": \"This binary has keylogging capabilities.\", \"ids\": [23], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports debugger functions.\", \"ids\": [6], \"tactics\": []}], \"kubernetesInfo\": {\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}, \"mitigationStatus\": [{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:44.336124Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:44.469734Z\", \"latestReport\": null, \"status\": \"success\"}], \"threatInfo\": {\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"CHIP DIGITAL GMBH\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"provider_unknown\", \"collectionId\": \"715723450695101689\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:14:44.069617Z\", \"detectionType\": \"static\", \"engines\": [\"On-Write DFI\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"EXE\", \"fileExtensionType\": \"Executable\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Ncat Netcat Portable - CHIP-Installer (1).exe\", \"fileSize\": 0, \"fileVerificationType\": \"SignedVerified\", \"identifiedAt\": \"2019-09-15T12:14:43.215000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": true, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"publisherName\": \"CHIP DIGITAL GMBH\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"ccce727e39cb8d955a323bf2c0419f31fb917e5a\", \"sha256\": null, \"storyline\": \"5F18360CAB4D45B7\", \"threatId\": \"715723450678324472\", \"threatName\": \"Ncat Netcat Portable - CHIP-Installer (1).exe\", \"updatedAt\": \"2020-04-02T14:52:28.537685Z\"}, \"whiteningOptions\": [\"path\", \"certificate\", \"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}", "occurred": "2019-09-15T12:14:44.069617Z", "rawJSON": "{\"agentDetectionInfo\": {\"accountId\": null, \"accountName\": null, \"agentDomain\": null, \"agentIpV4\": null, \"agentIpV6\": null, \"agentLastLoggedInUserName\": null, \"agentMitigationMode\": \"protect\", \"agentOsName\": null, \"agentOsRevision\": null, \"agentRegisteredAt\": null, \"agentUuid\": null, \"agentVersion\": \"3.1.3.38\", \"externalIp\": null, \"groupId\": null, \"groupName\": null, \"siteId\": null, \"siteName\": null}, \"agentRealtimeInfo\": {\"accountId\": \"433241117337583618\", \"accountName\": \"SentinelOne\", \"activeThreats\": 0, \"agentComputerName\": \"EC2AMAZ-AJ0KANC\", \"agentDecommissionedAt\": true, \"agentDomain\": \"WORKGROUP\", \"agentId\": \"657613730168123595\", \"agentInfected\": false, \"agentIsActive\": false, \"agentIsDecommissioned\": true, \"agentMachineType\": \"server\", \"agentMitigationMode\": \"protect\", \"agentNetworkStatus\": \"connecting\", \"agentOsName\": \"Windows Server 2016\", \"agentOsRevision\": \"14393\", \"agentOsType\": \"windows\", \"agentUuid\": \"f431b0a1a8744d2a8a92fc88fa3c13bc\", \"agentVersion\": \"3.1.3.38\", \"groupId\": \"475482421375116388\", \"groupName\": \"Default Group\", \"networkInterfaces\": [{\"id\": \"657613730176512204\", \"inet\": [\"8.8.8.8\"], \"inet6\": [\"fe80::1da3:1ca8:b311:af32\"], \"name\": \"Ethernet 2\", \"physical\": \"06:35:e6:62:53:2e\"}], \"operationalState\": \"na\", \"rebootRequired\": false, \"scanAbortedAt\": null, \"scanFinishedAt\": \"2019-06-30T15:34:52.505374Z\", \"scanStartedAt\": \"2019-06-30T15:01:17.500397Z\", \"scanStatus\": \"finished\", \"siteId\": \"475482421366727779\", \"siteName\": \"demisto\", \"userActionsNeeded\": []}, \"containerInfo\": {\"id\": null, \"image\": null, \"labels\": null, \"name\": null}, \"id\": \"715723450678324472\", \"indicators\": [{\"category\": \"General\", \"description\": \"This is an AutoIT script compiled to an exe file.\", \"ids\": [25], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports functions used to raise kernel exceptions.\", \"ids\": [24], \"tactics\": []}, {\"category\": \"InfoStealer\", \"description\": \"This binary has keylogging capabilities.\", \"ids\": [23], \"tactics\": []}, {\"category\": \"General\", \"description\": \"This binary imports debugger functions.\", \"ids\": [6], \"tactics\": []}], \"kubernetesInfo\": {\"cluster\": null, \"controllerKind\": null, \"controllerLabels\": null, \"controllerName\": null, \"namespace\": null, \"namespaceLabels\": null, \"node\": null, \"pod\": null, \"podLabels\": null}, \"mitigationStatus\": [{\"action\": \"kill\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:44.336124Z\", \"latestReport\": null, \"status\": \"success\"}, {\"action\": \"quarantine\", \"actionsCounters\": null, \"groupNotFound\": false, \"lastUpdate\": \"2019-09-15T12:14:44.469734Z\", \"latestReport\": null, \"status\": \"success\"}], \"threatInfo\": {\"analystVerdict\": \"undefined\", \"analystVerdictDescription\": \"Undefined\", \"automaticallyResolved\": false, \"browserType\": null, \"certificateId\": \"CHIP DIGITAL GMBH\", \"classification\": \"Malware\", \"classificationSource\": \"Static\", \"cloudFilesHashVerdict\": \"provider_unknown\", \"collectionId\": \"715723450695101689\", \"confidenceLevel\": \"malicious\", \"createdAt\": \"2019-09-15T12:14:44.069617Z\", \"detectionType\": \"static\", \"engines\": [\"On-Write DFI\"], \"externalTicketExists\": false, \"externalTicketId\": null, \"failedActions\": false, \"fileExtension\": \"EXE\", \"fileExtensionType\": \"Executable\", \"filePath\": \"\\\\Device\\\\HarddiskVolume1\\\\Users\\\\Administrator\\\\Downloads\\\\Ncat Netcat Portable - CHIP-Installer (1).exe\", \"fileSize\": 0, \"fileVerificationType\": \"SignedVerified\", \"identifiedAt\": \"2019-09-15T12:14:43.215000Z\", \"incidentStatus\": \"resolved\", \"incidentStatusDescription\": \"Resolved\", \"initiatedBy\": \"agent_policy\", \"initiatedByDescription\": \"Agent Policy\", \"initiatingUserId\": null, \"initiatingUsername\": null, \"isFileless\": false, \"isValidCertificate\": true, \"maliciousProcessArguments\": null, \"md5\": null, \"mitigatedPreemptively\": false, \"mitigationStatus\": \"mitigated\", \"mitigationStatusDescription\": \"Mitigated\", \"originatorProcess\": null, \"pendingActions\": false, \"processUser\": \"EC2AMAZ-AJ0KANC\\\\Administrator\", \"publisherName\": \"CHIP DIGITAL GMBH\", \"reachedEventsLimit\": false, \"rebootRequired\": false, \"sha1\": \"ccce727e39cb8d955a323bf2c0419f31fb917e5a\", \"sha256\": null, \"storyline\": \"5F18360CAB4D45B7\", \"threatId\": \"715723450678324472\", \"threatName\": \"Ncat Netcat Portable - CHIP-Installer (1).exe\", \"updatedAt\": \"2020-04-02T14:52:28.537685Z\"}, \"whiteningOptions\": [\"path\", \"certificate\", \"hash\"], \"mirror_direction\": null, \"mirror_instance\": \"\", \"incident_type\": \"SentinelOne Incident\"}" } diff --git a/Packs/SentinelOne/ReleaseNotes/3_2_22.md b/Packs/SentinelOne/ReleaseNotes/3_2_22.md new file mode 100644 index 000000000000..829f13f4b195 --- /dev/null +++ b/Packs/SentinelOne/ReleaseNotes/3_2_22.md @@ -0,0 +1,4 @@ +#### Integrations +##### SentinelOne v2 +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. +- Updated the incident context data by removing the both details and labels. diff --git a/Packs/SentinelOne/pack_metadata.json b/Packs/SentinelOne/pack_metadata.json index f3ecb46894a6..227b88c6e7ac 100644 --- a/Packs/SentinelOne/pack_metadata.json +++ b/Packs/SentinelOne/pack_metadata.json @@ -2,7 +2,7 @@ "name": "SentinelOne", "description": "Endpoint protection", "support": "partner", - "currentVersion": "3.2.21", + "currentVersion": "3.2.22", "author": "SentinelOne", "url": "https://www.sentinelone.com/support/", "email": "support@sentinelone.com", From b2ec6f4cc6dcfe029cd6cbcc6a15b4b15aa1e39a Mon Sep 17 00:00:00 2001 From: Moshe Eichler <78307768+MosheEichler@users.noreply.github.com> Date: Sun, 25 Feb 2024 12:53:05 +0200 Subject: [PATCH 075/272] Exclude nightly ok in contribution PRs (#33087) * Exclude nightly ok in contrib PRs * change name * space * more space --- ...eck-nightly-ok-label.yml => check-nightly-ok-label.yml} | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) rename .github/workflows/{ckeck-nightly-ok-label.yml => check-nightly-ok-label.yml} (85%) diff --git a/.github/workflows/ckeck-nightly-ok-label.yml b/.github/workflows/check-nightly-ok-label.yml similarity index 85% rename from .github/workflows/ckeck-nightly-ok-label.yml rename to .github/workflows/check-nightly-ok-label.yml index 70959ad08eac..f2a52c95c594 100644 --- a/.github/workflows/ckeck-nightly-ok-label.yml +++ b/.github/workflows/check-nightly-ok-label.yml @@ -7,6 +7,7 @@ on: jobs: check_label: runs-on: ubuntu-latest + if: github.repository == 'demisto/content' && github.event.pull_request.head.repo.fork == false steps: - name: Checkout repo @@ -21,12 +22,12 @@ jobs: echo "All changed files:" echo "${CHANGED_FILES}" GITLAB_CHANGED_FILES=$( [[ $CHANGED_FILES == *".gitlab/ci"* ]] && echo true || echo false) - echo "Files in the.gitlab folder have changed: ${GITLAB_CHANGED_FILES}" + echo "Files in the .gitlab folder have changed: ${GITLAB_CHANGED_FILES}" echo "gitlab_changed_files=$GITLAB_CHANGED_FILES" >> $GITHUB_OUTPUT if [[ $GITLAB_CHANGED_FILES == true ]]; then echo 'Files under .gitlab folder has changed, Will check if the PR has the `nightly-ok` label.' else - echo 'Files in the.gitlab folder have not been changed.' + echo 'Files in the .gitlab folder have not been changed.' fi - name: Check if PR has the nightly-ok label @@ -46,5 +47,5 @@ jobs: process.exit(1); // Exit with failure status if label is missing } } else { - console.log('Files in the.gitlab folder have not been changed.'); + console.log('Files in the .gitlab folder have not been changed.'); } From 57e6a1d7a10dbe8da8ff975b3dc39228a839a936 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 25 Feb 2024 13:53:19 +0200 Subject: [PATCH 076/272] [Marketplace Contribution] XSOAR File Management - Content Pack Update (#32961) (#33086) * "contribution update to pack "XSOAR File Management"" * Update Packs/XSOARFileManagement/Integrations/XSOARFileManagement/XSOARFileManagement.py * Update Packs/XSOARFileManagement/ReleaseNotes/1_1_0.md * Update Packs/XSOARFileManagement/ReleaseNotes/1_1_0.md --------- Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: amontminypa <118302525+amontminypa@users.noreply.github.com> Co-authored-by: JudithB <132264628+jbabazadeh@users.noreply.github.com> --- .../XSOARFileManagement/XSOARFileManagement.py | 16 +++++++++++----- .../XSOARFileManagement/XSOARFileManagement.yml | 8 +++++++- Packs/XSOARFileManagement/ReleaseNotes/1_1_0.md | 9 +++++++++ Packs/XSOARFileManagement/pack_metadata.json | 12 ++++++++---- 4 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 Packs/XSOARFileManagement/ReleaseNotes/1_1_0.md diff --git a/Packs/XSOARFileManagement/Integrations/XSOARFileManagement/XSOARFileManagement.py b/Packs/XSOARFileManagement/Integrations/XSOARFileManagement/XSOARFileManagement.py index 010fd0c2eeb4..63721ac4359f 100644 --- a/Packs/XSOARFileManagement/Integrations/XSOARFileManagement/XSOARFileManagement.py +++ b/Packs/XSOARFileManagement/Integrations/XSOARFileManagement/XSOARFileManagement.py @@ -1,5 +1,7 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 + + import re import time from typing import Tuple @@ -63,7 +65,7 @@ def delete_context(self, incident_id: str, key_to_delete: str): ) return response - def delete_file(self, entry_id: str, delete_artifact=True): + def delete_file(self, incident_id, entry_id: str, delete_artifact=True): """Delete file by entry ID Arguments: client: (Client) The client class. @@ -74,7 +76,9 @@ def delete_file(self, entry_id: str, delete_artifact=True): """ body_content = { "id": entry_id, - "deleteArtifact": delete_artifact + "deleteArtifact": delete_artifact, + "version": 0, + "investigationId": incident_id } response = self._http_request( method='POST', @@ -297,13 +301,13 @@ def delete_attachment_command(client: Client, args: dict) -> CommandResults: def delete_file(client: Client, entry_id: str): files = demisto.context().get('File', []) files = [files] if not isinstance(files, list) else files + incident_id = get_incident_id(entry_id) # delete old file try: - client.delete_file(entry_id) + client.delete_file(incident_id, entry_id) except DemistoException as error: return_error(f"File already deleted or not found !\n{str(error)}") # output - incident_id = get_incident_id(entry_id) client.delete_context(incident_id, "File") time.sleep(1) # to let the API execute the request new_files = [file for file in files if file.get("EntryID") != entry_id] @@ -432,6 +436,7 @@ def main() -> None: command = demisto.command() api_key = demisto.get(demisto.params(), 'creds_apikey.password') + api_key_id = demisto.params().get("creds_apikey_id", {}).get("password") server_url = demisto.demistoUrls()["server"] base_url = params.get('url', server_url) verify_certificate = not params.get('insecure', False) @@ -439,7 +444,8 @@ def main() -> None: try: headers = { - 'Authorization': api_key + 'Authorization': api_key, + 'x-xdr-auth-id': api_key_id } client = Client( base_url=base_url, diff --git a/Packs/XSOARFileManagement/Integrations/XSOARFileManagement/XSOARFileManagement.yml b/Packs/XSOARFileManagement/Integrations/XSOARFileManagement/XSOARFileManagement.yml index 6141652c57d9..45b6f7823332 100644 --- a/Packs/XSOARFileManagement/Integrations/XSOARFileManagement/XSOARFileManagement.yml +++ b/Packs/XSOARFileManagement/Integrations/XSOARFileManagement/XSOARFileManagement.yml @@ -22,6 +22,12 @@ configuration: name: proxy type: 8 required: false +- display: '' + displaypassword: XSOAR Server API Key ID + hiddenusername: true + name: creds_apikey_id + required: false + type: 9 description: This integration uses the XSOAR API to perform basic but essentials actions on files. display: XSOAR File Management name: XSOAR File Management @@ -85,7 +91,7 @@ script: required: true description: 'Rename a file. Warning: use this only if necessary, it''s HEAVY to run, this will delete and recreate the file with another name.' name: file-management-rename-file - dockerimage: demisto/python3:3.10.13.78960 + dockerimage: demisto/python3:3.10.13.87159 runonce: false script: '' subtype: python3 diff --git a/Packs/XSOARFileManagement/ReleaseNotes/1_1_0.md b/Packs/XSOARFileManagement/ReleaseNotes/1_1_0.md new file mode 100644 index 000000000000..bbbef95b275f --- /dev/null +++ b/Packs/XSOARFileManagement/ReleaseNotes/1_1_0.md @@ -0,0 +1,9 @@ + +#### Integrations + +##### XSOAR File Management + +- Added an additional parameter **XSOAR Server API Key ID** for XSOAR 8. +- Updated the **file-management-delete-file** command to support delete file in XSOAR 8. + +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/XSOARFileManagement/pack_metadata.json b/Packs/XSOARFileManagement/pack_metadata.json index bae4301d70c5..8aecf97cba16 100644 --- a/Packs/XSOARFileManagement/pack_metadata.json +++ b/Packs/XSOARFileManagement/pack_metadata.json @@ -2,15 +2,19 @@ "name": "XSOAR File Management", "description": "This pack let user manipulate file inside XSOAR more easily than with the builtin functions.", "support": "community", - "currentVersion": "1.0.2", + "currentVersion": "1.1.0", "author": "Pierre", "url": "", "email": "", "created": "2023-02-07T13:03:55Z", - "categories": ["Utilities"], + "categories": [ + "Utilities" + ], "tags": [], "useCases": [], - "keywords": ["File"], + "keywords": [ + "File" + ], "marketplaces": [ "xsoar", "marketplacev2" @@ -18,4 +22,4 @@ "githubUser": [ "Winultimatum" ] -} +} \ No newline at end of file From b05bbd3fe6232578d5e975b3590a837fa1a0ebca Mon Sep 17 00:00:00 2001 From: Karina Fishman <147307864+karinafishman@users.noreply.github.com> Date: Sun, 25 Feb 2024 14:32:40 +0200 Subject: [PATCH 077/272] Convert file hash to corresponding hash improvement (#33001) * added another method to search for indicators * release notes updated * added length check for hashes * RM update * Update Packs/CommonPlaybooks/ReleaseNotes/2_6_14.md Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Update Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes.yml Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --------- Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- ...vert_file_hash_to_corresponding_hashes.yml | 531 ++++++++++++++++-- ...ile_hash_to_corresponding_hashes_README.md | 43 +- Packs/CommonPlaybooks/ReleaseNotes/2_6_14.md | 6 + ...vert_file_hash_to_corresponding_hashes.png | Bin 0 -> 194615 bytes Packs/CommonPlaybooks/pack_metadata.json | 2 +- 5 files changed, 509 insertions(+), 73 deletions(-) create mode 100644 Packs/CommonPlaybooks/ReleaseNotes/2_6_14.md create mode 100644 Packs/CommonPlaybooks/doc_files/Convert_file_hash_to_corresponding_hashes.png diff --git a/Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes.yml b/Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes.yml index d17009150973..efde48091457 100644 --- a/Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes.yml +++ b/Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes.yml @@ -35,6 +35,10 @@ tasks: note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "2": id: "2" taskid: d0c581d2-789c-4a12-8940-37f17a47b4f6 @@ -51,13 +55,17 @@ tasks: view: |- { "position": { - "x": 520, - "y": 970 + "x": 530, + "y": 950 } } note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "4": id: "4" taskid: b797fdc7-1704-442a-8605-ee06bfb0bf54 @@ -74,7 +82,7 @@ tasks: '#default#': - "2" "yes": - - "18" + - "44" separatecontext: false conditions: - label: "yes" @@ -88,13 +96,17 @@ tasks: view: |- { "position": { - "x": 970, - "y": 240 + "x": 1080, + "y": 200 } } note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "9": id: "9" taskid: f7142eb2-9483-4546-8d07-a828d636d0ad @@ -111,7 +123,7 @@ tasks: '#default#': - "2" "yes": - - "16" + - "46" separatecontext: false conditions: - label: "yes" @@ -125,13 +137,17 @@ tasks: view: |- { "position": { - "x": -250, - "y": 240 + "x": -40, + "y": 190 } } note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "10": id: "10" taskid: eff5d9b7-ea36-4310-8650-5e26fa38209e @@ -148,7 +164,7 @@ tasks: '#default#': - "2" "yes": - - "15" + - "45" separatecontext: false conditions: - label: "yes" @@ -159,16 +175,23 @@ tasks: complex: root: inputs.SHA1 iscontext: true + right: + value: {} + continueonerrortype: "" view: |- { "position": { "x": 520, - "y": 230 + "y": 190 } } note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "15": id: "15" taskid: 65ff1c51-6bc1-4171-8bde-eb6ecb862f4e @@ -186,32 +209,26 @@ tasks: '#none#': - "2" scriptarguments: - confidenceThreshold: {} file: complex: root: inputs.SHA1 - include_inactive: {} - long: {} - md5: {} - owners: {} - ratingThreshold: {} - retries: {} - sha256: {} - threshold: {} - wait: {} reputationcalc: 2 continueonerror: true separatecontext: false view: |- { "position": { - "x": 310, - "y": 410 + "x": 300, + "y": 750 } } note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "16": id: "16" taskid: 9e3c8b51-dbc6-464a-8af7-f5d43b663bd4 @@ -233,28 +250,23 @@ tasks: file: complex: root: inputs.MD5 - include_inactive: {} - long: {} - md5: {} - owners: {} - ratingThreshold: {} - retries: {} - sha256: {} - threshold: {} - wait: {} reputationcalc: 2 continueonerror: true separatecontext: false view: |- { "position": { - "x": -490, - "y": 410 + "x": -550, + "y": 750 } } note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "18": id: "18" taskid: 29ef7703-de75-4ff3-844c-a852e333bdbe @@ -276,28 +288,23 @@ tasks: file: complex: root: inputs.SHA256 - include_inactive: {} - long: {} - md5: {} - owners: {} - ratingThreshold: {} - retries: {} - sha256: {} - threshold: {} - wait: {} reputationcalc: 2 continueonerror: true separatecontext: false view: |- { "position": { - "x": 1230, - "y": 410 + "x": 1180, + "y": 750 } } note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "35": id: "35" taskid: fdfd1cd9-3095-455b-8481-072b140ee5de @@ -317,13 +324,17 @@ tasks: view: |- { "position": { - "x": -250, - "y": 115 + "x": -40, + "y": 60 } } note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "36": id: "36" taskid: a75bc19c-d514-44ab-885d-fb6664dd0b29 @@ -344,12 +355,16 @@ tasks: { "position": { "x": 520, - "y": 115 + "y": 60 } } note: false timertriggers: [] ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false "37": id: "37" taskid: a2d56e80-d468-46a0-891d-3792a6bf0bd9 @@ -369,25 +384,425 @@ tasks: view: |- { "position": { - "x": 970, - "y": 110 + "x": 1080, + "y": 60 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "39": + id: "39" + taskid: 336d7e69-334b-490c-81c4-4b48788a56be + type: condition + task: + id: 336d7e69-334b-490c-81c4-4b48788a56be + version: -1 + name: Have the hashes been retrieved? + type: condition + iscommand: false + brand: "" + description: "" + nexttasks: + '#default#': + - "18" + "yes": + - "40" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: foundIndicators.value + iscontext: true + right: + value: {} + - - operator: stringHasLength + left: + value: + complex: + root: foundIndicators + accessor: value + iscontext: true + right: + value: + simple: "64" + continueonerrortype: "" + view: |- + { + "position": { + "x": 1350, + "y": 540 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "40": + id: "40" + taskid: 4cbe3c2a-dc3d-46fc-8b6a-b589accfdba3 + type: regular + task: + id: 4cbe3c2a-dc3d-46fc-8b6a-b589accfdba3 + version: -1 + name: Enrich indicators + description: commands.local.cmd.enrich.indicators + script: Builtin|||enrichIndicators + type: regular + iscommand: true + brand: Builtin + nexttasks: + '#none#': + - "2" + scriptarguments: + indicatorsValues: + complex: + root: foundIndicators + accessor: value + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 1600, + "y": 750 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "44": + id: "44" + taskid: b27dc11a-1b9f-4056-8288-776eaa57bd63 + type: regular + task: + id: b27dc11a-1b9f-4056-8288-776eaa57bd63 + version: -1 + name: Search indicators + description: |- + Searches Cortex XSOAR indicators. + + Searches for Cortex XSOAR indicators and returns the id, indicator_type, value, and score/verdict. + + You can add additional fields from the indicators using the add_field_to_context argument. + scriptName: SearchIndicator + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "39" + scriptarguments: + query: + simple: value:${inputs.SHA256} + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 1350, + "y": 370 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "45": + id: "45" + taskid: 1b49a035-86f4-4e1d-81ac-add593725d88 + type: regular + task: + id: 1b49a035-86f4-4e1d-81ac-add593725d88 + version: -1 + name: Search indicators + description: |- + Searches Cortex XSOAR indicators. + + Searches for Cortex XSOAR Indicators and returns the id, indicator_type, value, and score/verdict. + + You can add additional fields from the indicators using the add_field_to_context argument. + scriptName: SearchIndicator + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "47" + scriptarguments: + query: + simple: value:${inputs.SHA1} + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 520, + "y": 370 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "46": + id: "46" + taskid: f9974076-074f-4bf4-82a5-0c804fb7875b + type: regular + task: + id: f9974076-074f-4bf4-82a5-0c804fb7875b + version: -1 + name: Search indicators + description: |- + Searches Cortex XSOAR indicators. + + Searches for Cortex XSOAR Indicators and returns the id, indicator_type, value, and score/verdict. + + You can add additional fields from the indicators using the add_field_to_context argument. + scriptName: SearchIndicator + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "48" + scriptarguments: + query: + simple: value:${inputs.MD5} + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": -330, + "y": 370 } } note: false timertriggers: [] ignoreworker: false -system: true + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "47": + id: "47" + taskid: 0161e3d5-ca7c-4e0e-86d4-f767f1c7b64c + type: condition + task: + id: 0161e3d5-ca7c-4e0e-86d4-f767f1c7b64c + version: -1 + name: Have the hashes been retrieved? + type: condition + iscommand: false + brand: "" + description: "" + nexttasks: + '#default#': + - "15" + "yes": + - "49" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: foundIndicators.value + iscontext: true + right: + value: {} + - - operator: stringHasLength + left: + value: + complex: + root: foundIndicators + accessor: value + iscontext: true + right: + value: + simple: "40" + continueonerrortype: "" + view: |- + { + "position": { + "x": 520, + "y": 540 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "48": + id: "48" + taskid: 9fb9988f-d614-4a30-8eb9-09c8a05ad461 + type: condition + task: + id: 9fb9988f-d614-4a30-8eb9-09c8a05ad461 + version: -1 + name: Have the hashes been retrieved? + type: condition + iscommand: false + brand: "" + description: "" + nexttasks: + '#default#': + - "16" + "yes": + - "50" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + simple: foundIndicators.value + iscontext: true + right: + value: {} + - - operator: stringHasLength + left: + value: + complex: + root: foundIndicators + accessor: value + iscontext: true + right: + value: + simple: "32" + continueonerrortype: "" + view: |- + { + "position": { + "x": -330, + "y": 540 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "49": + id: "49" + taskid: 620476dc-83d3-40fe-8d2f-8f978fcdfa23 + type: regular + task: + id: 620476dc-83d3-40fe-8d2f-8f978fcdfa23 + version: -1 + name: Enrich indicators + description: commands.local.cmd.enrich.indicators + script: Builtin|||enrichIndicators + type: regular + iscommand: true + brand: Builtin + nexttasks: + '#none#': + - "2" + scriptarguments: + indicatorsValues: + complex: + root: foundIndicators + accessor: value + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 750, + "y": 750 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "50": + id: "50" + taskid: e4213b2e-29ba-40d3-8ae3-6deec5436549 + type: regular + task: + id: e4213b2e-29ba-40d3-8ae3-6deec5436549 + version: -1 + name: Enrich indicators + description: commands.local.cmd.enrich.indicators + script: Builtin|||enrichIndicators + type: regular + iscommand: true + brand: Builtin + nexttasks: + '#none#': + - "2" + scriptarguments: + indicatorsValues: + complex: + root: foundIndicators + accessor: value + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": -120, + "y": 750 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false view: |- { "linkLabelsPosition": { - "10_15_yes": 0.55, - "9_16_yes": 0.48 + "10_2_#default#": 0.39, + "10_45_yes": 0.46, + "47_15_#default#": 0.44, + "47_49_yes": 0.41, + "48_16_#default#": 0.57, + "48_50_yes": 0.61, + "4_2_#default#": 0.15, + "9_2_#default#": 0.19, + "9_46_yes": 0.51 }, "paper": { "dimensions": { - "height": 1135, - "width": 2100, - "x": -490, + "height": 1115, + "width": 2530, + "x": -550, "y": -100 } } @@ -400,6 +815,7 @@ inputs: accessor: SHA256 required: false description: The SHA256 hash on which to search. + playbookInputQuery: - key: SHA1 value: complex: @@ -407,6 +823,7 @@ inputs: accessor: SHA1 required: false description: The SHA1 hash on which to search. + playbookInputQuery: - key: MD5 value: complex: @@ -414,6 +831,7 @@ inputs: accessor: MD5 required: false description: The MD5 hash on which to search. + playbookInputQuery: outputs: - contextPath: File.SHA256 description: Output for detected SHA256 hash. @@ -424,6 +842,7 @@ outputs: - contextPath: File.MD5 description: Output for detected MD5 hash. type: string - +- contextPath: Indicators.Value + description: Output for detected hashes. tests: - Test Convert file hash to corresponding hashes diff --git a/Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes_README.md b/Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes_README.md index cdb0d2320e98..5eaeb105ee68 100644 --- a/Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes_README.md +++ b/Packs/CommonPlaybooks/Playbooks/playbook-Convert_file_hash_to_corresponding_hashes_README.md @@ -1,41 +1,52 @@ -Gets all of the corresponding hashes for a file even if there is only one hash type available. -For example, if we have only the SHA256 hash, the playbook will get the SHA1 hash and MD5 hash as long as the +The playbook enables you to get all of the corresponding file hashes for a file even if there is only one hash type available. +For example, if we have only the SHA256 hash, the playbook will get the SHA1 and MD5 hashes as long as the original searched hash is recognized by any our the threat intelligence integrations. ## Dependencies + This playbook uses the following sub-playbooks, integrations, and scripts. -## Sub-playbooks +### Sub-playbooks + This playbook does not use any sub-playbooks. -## Integrations +### Integrations + This playbook does not use any integrations. -## Scripts -This playbook does not use any scripts. +### Scripts + +* SearchIndicator + +### Commands -## Commands +* enrichIndicators * file ## Playbook Inputs + --- -| **Name** | **Description** | **Default Value** | **Source** | **Required** | -| --- | --- | --- | --- | --- | -| SHA256 | The SHA256 hash on which to search. | SHA256 | File | Optional | -| SHA1 | The SHA1 hash on which to search. | SHA1 | File | Optional | -| MD5 | The MD5 hash on which to search. | MD5 | File | Optional | +| **Name** | **Description** | **Default Value** | **Required** | +| --- | --- | --- | --- | +| SHA256 | The SHA256 hash on which to search. | File.SHA256 | Optional | +| SHA1 | The SHA1 hash on which to search. | File.SHA1 | Optional | +| MD5 | The MD5 hash on which to search. | File.MD5 | Optional | ## Playbook Outputs + --- | **Path** | **Description** | **Type** | | --- | --- | --- | -| File.SHA256 | The output for detected SHA256 hash of the file. | string | -| File.SHA1 | The output for detected SHA1 hash of the file. | string | -| File.MD5 | The output for detected MD5 hash of the file. | string | +| File.SHA256 | Output for detected SHA256 hash. | string | +| File.SHA1 | Output for detected SHA1 hash. | string | +| File.MD5 | Output for detected MD5 hash. | string | +| Indicators.Value | Output for detected hashes. | unknown | ## Playbook Image + --- -![Convert_file_hash_to_corresponding_hashes](https://raw.githubusercontent.com/demisto/content/1bdd5229392bd86f0cc58265a24df23ee3f7e662/docs/images/playbooks/Convert_file_hash_to_corresponding_hashes.png) + +![Convert file hash to corresponding hashes](../doc_files/Convert_file_hash_to_corresponding_hashes.png) diff --git a/Packs/CommonPlaybooks/ReleaseNotes/2_6_14.md b/Packs/CommonPlaybooks/ReleaseNotes/2_6_14.md new file mode 100644 index 000000000000..8de82ff6685c --- /dev/null +++ b/Packs/CommonPlaybooks/ReleaseNotes/2_6_14.md @@ -0,0 +1,6 @@ + +#### Playbooks + +##### Convert file hash to corresponding hashes + +Added local search for hashes in Cortex XSOAR before the enrichment. diff --git a/Packs/CommonPlaybooks/doc_files/Convert_file_hash_to_corresponding_hashes.png b/Packs/CommonPlaybooks/doc_files/Convert_file_hash_to_corresponding_hashes.png new file mode 100644 index 0000000000000000000000000000000000000000..a0c0a06d6e546c62d2acccfb4749a541f5fa1073 GIT binary patch literal 194615 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

    m?o%_#yZ4S6RVb|-uA#hV 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 F2>|%huWA4Q literal 0 HcmV?d00001 diff --git a/Packs/CommonPlaybooks/pack_metadata.json b/Packs/CommonPlaybooks/pack_metadata.json index 631caf643255..8a256d0b7ad8 100644 --- a/Packs/CommonPlaybooks/pack_metadata.json +++ b/Packs/CommonPlaybooks/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Playbooks", "description": "Frequently used playbooks pack.", "support": "xsoar", - "currentVersion": "2.6.13", + "currentVersion": "2.6.14", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 41e6cd790b2cb6f00199bd5a2fb567a8bdf36e00 Mon Sep 17 00:00:00 2001 From: Jacob Levy <129657918+jlevypaloalto@users.noreply.github.com> Date: Sun, 25 Feb 2024 14:59:29 +0200 Subject: [PATCH 078/272] Fix QRadar TPB (#33003) * init * remove hard-coded test * change test order --- Packs/QRadar/TestPlaybooks/QRadar_v3-test.yml | 550 ++++++++---------- 1 file changed, 229 insertions(+), 321 deletions(-) diff --git a/Packs/QRadar/TestPlaybooks/QRadar_v3-test.yml b/Packs/QRadar/TestPlaybooks/QRadar_v3-test.yml index ccfdb0f13c8d..b153c27b3ab5 100644 --- a/Packs/QRadar/TestPlaybooks/QRadar_v3-test.yml +++ b/Packs/QRadar/TestPlaybooks/QRadar_v3-test.yml @@ -6,10 +6,10 @@ starttaskid: "0" tasks: "0": id: "0" - taskid: 920c22d6-d535-4a6a-8ab7-58ebbeed976d + taskid: 719bc689-fc55-4293-867b-a496071a4a62 type: start task: - id: 920c22d6-d535-4a6a-8ab7-58ebbeed976d + id: 719bc689-fc55-4293-867b-a496071a4a62 version: -1 name: "" iscommand: false @@ -37,10 +37,10 @@ tasks: isautoswitchedtoquietmode: false "1": id: "1" - taskid: b6090a27-fb18-43d0-8585-a8502f704ece + taskid: ffcc9925-d8a6-4cc8-83f4-25b7dee1bd0a type: regular task: - id: b6090a27-fb18-43d0-8585-a8502f704ece + id: ffcc9925-d8a6-4cc8-83f4-25b7dee1bd0a version: -1 name: Delete Context description: Delete field from context @@ -72,10 +72,10 @@ tasks: isautoswitchedtoquietmode: false "2": id: "2" - taskid: 0031d449-012e-4f09-89af-8843cfb474bb + taskid: bae46329-059b-4c23-80f1-6d5693d8e39d type: regular task: - id: 0031d449-012e-4f09-89af-8843cfb474bb + id: bae46329-059b-4c23-80f1-6d5693d8e39d version: -1 name: Offense List description: Gets offenses from QRadar. @@ -107,10 +107,10 @@ tasks: isautoswitchedtoquietmode: false "3": id: "3" - taskid: eae7aeda-15b8-4f95-80ad-df5141a21d4f + taskid: acb1b2f3-a227-45ec-8c96-e02ce373d977 type: condition task: - id: eae7aeda-15b8-4f95-80ad-df5141a21d4f + id: acb1b2f3-a227-45ec-8c96-e02ce373d977 version: -1 name: Validate Outputs type: condition @@ -118,7 +118,7 @@ tasks: brand: "" nexttasks: "yes": - - "76" + - "65" separatecontext: false conditions: - label: "yes" @@ -175,10 +175,10 @@ tasks: isautoswitchedtoquietmode: false "4": id: "4" - taskid: 422d210b-e693-4775-8344-bd3f118b777f + taskid: 7e1cd761-cf7e-4a0f-873f-81b1b39011d8 type: title task: - id: 422d210b-e693-4775-8344-bd3f118b777f + id: 7e1cd761-cf7e-4a0f-873f-81b1b39011d8 version: -1 name: Test Playbook Done type: title @@ -191,7 +191,7 @@ tasks: { "position": { "x": 265, - "y": 13145 + "y": 12795 } } note: false @@ -203,10 +203,10 @@ tasks: isautoswitchedtoquietmode: false "5": id: "5" - taskid: 9d03d619-0f8e-49fa-8d29-e675cefd8f53 + taskid: 0a2c3e34-398f-4008-82d8-95fb32a7676a type: regular task: - id: 9d03d619-0f8e-49fa-8d29-e675cefd8f53 + id: 0a2c3e34-398f-4008-82d8-95fb32a7676a version: -1 name: Update Offense description: Update an offense. @@ -230,7 +230,7 @@ tasks: { "position": { "x": 265, - "y": 1245 + "y": 1420 } } note: false @@ -242,10 +242,10 @@ tasks: isautoswitchedtoquietmode: false "7": id: "7" - taskid: f8758e44-edb6-445f-8048-7df84b0a5da4 + taskid: 6298fc72-ccf0-43eb-8acd-44ee1b22a559 type: condition task: - id: f8758e44-edb6-445f-8048-7df84b0a5da4 + id: 6298fc72-ccf0-43eb-8acd-44ee1b22a559 version: -1 name: Validate Outputs type: condition @@ -284,7 +284,7 @@ tasks: { "position": { "x": 265, - "y": 1420 + "y": 1595 } } note: false @@ -296,10 +296,10 @@ tasks: isautoswitchedtoquietmode: false "8": id: "8" - taskid: 5c752027-a780-41c2-8560-f8b8fcb4b5ff + taskid: e7b4bed3-863f-4f4a-872c-7c0855809e0c type: regular task: - id: 5c752027-a780-41c2-8560-f8b8fcb4b5ff + id: e7b4bed3-863f-4f4a-872c-7c0855809e0c version: -1 name: Create Note To Offense description: Retrieve a list of notes for an offense. @@ -321,7 +321,7 @@ tasks: { "position": { "x": 265, - "y": 1595 + "y": 1770 } } note: false @@ -333,10 +333,10 @@ tasks: isautoswitchedtoquietmode: false "9": id: "9" - taskid: 05299b7e-88af-42fb-8fc4-e3011ad328bb + taskid: 4eb48d1e-a77f-48a2-8f03-f1c2b27a69e3 type: condition task: - id: 05299b7e-88af-42fb-8fc4-e3011ad328bb + id: 4eb48d1e-a77f-48a2-8f03-f1c2b27a69e3 version: -1 name: Validate Outputs type: condition @@ -370,7 +370,7 @@ tasks: { "position": { "x": 265, - "y": 1770 + "y": 1945 } } note: false @@ -382,10 +382,10 @@ tasks: isautoswitchedtoquietmode: false "10": id: "10" - taskid: 22c04981-8901-4976-87d2-f5727eb3febd + taskid: 7e337e57-9706-43bd-8928-abe1f0bf504e type: regular task: - id: 22c04981-8901-4976-87d2-f5727eb3febd + id: 7e337e57-9706-43bd-8928-abe1f0bf504e version: -1 name: Note List description: Create a note on an offense. @@ -409,7 +409,7 @@ tasks: { "position": { "x": 265, - "y": 1945 + "y": 2120 } } note: false @@ -421,10 +421,10 @@ tasks: isautoswitchedtoquietmode: false "11": id: "11" - taskid: 7df6f5f6-08eb-4f4f-8b33-53a3c8ee9c2e + taskid: 54b64eb2-9f9a-4349-8ffa-547ac73d4a87 type: condition task: - id: 7df6f5f6-08eb-4f4f-8b33-53a3c8ee9c2e + id: 54b64eb2-9f9a-4349-8ffa-547ac73d4a87 version: -1 name: Validate Outputs type: condition @@ -450,7 +450,7 @@ tasks: { "position": { "x": 265, - "y": 2120 + "y": 2295 } } note: false @@ -462,10 +462,10 @@ tasks: isautoswitchedtoquietmode: false "13": id: "13" - taskid: fa93b508-4022-4c10-8044-23a896c298da + taskid: b9d7599c-4f33-4ec1-8ffb-df63f3ba67b4 type: regular task: - id: fa93b508-4022-4c10-8044-23a896c298da + id: b9d7599c-4f33-4ec1-8ffb-df63f3ba67b4 version: -1 name: Get Closing Reasons List description: Retrieve a list of offense closing reasons. @@ -485,7 +485,7 @@ tasks: { "position": { "x": 265, - "y": 2295 + "y": 2470 } } note: false @@ -497,10 +497,10 @@ tasks: isautoswitchedtoquietmode: false "14": id: "14" - taskid: cc9be382-b2d2-40a9-8d1a-d743c219b8d3 + taskid: 2b36d39a-cb33-4ad6-8a8d-fd773f424b31 type: condition task: - id: cc9be382-b2d2-40a9-8d1a-d743c219b8d3 + id: 2b36d39a-cb33-4ad6-8a8d-fd773f424b31 version: -1 name: Validate Outputs type: condition @@ -558,7 +558,7 @@ tasks: { "position": { "x": 265, - "y": 2470 + "y": 2645 } } note: false @@ -570,10 +570,10 @@ tasks: isautoswitchedtoquietmode: false "15": id: "15" - taskid: a51b1410-efdf-4f75-83a3-9c5f11208cd1 + taskid: 6af7c4d5-8f82-451a-8306-0a3b203d1d40 type: regular task: - id: a51b1410-efdf-4f75-83a3-9c5f11208cd1 + id: 6af7c4d5-8f82-451a-8306-0a3b203d1d40 version: -1 name: Rules List description: Retrieves a list of rules. @@ -595,7 +595,7 @@ tasks: { "position": { "x": 265, - "y": 2645 + "y": 2820 } } note: false @@ -607,10 +607,10 @@ tasks: isautoswitchedtoquietmode: false "16": id: "16" - taskid: 51105aa9-f405-4751-8f48-ce385fbfee65 + taskid: 38aa7153-1256-4783-8979-1ff23d73a398 type: condition task: - id: 51105aa9-f405-4751-8f48-ce385fbfee65 + id: 38aa7153-1256-4783-8979-1ff23d73a398 version: -1 name: Validate Outputs type: condition @@ -692,7 +692,7 @@ tasks: { "position": { "x": 265, - "y": 2820 + "y": 2995 } } note: false @@ -704,10 +704,10 @@ tasks: isautoswitchedtoquietmode: false "17": id: "17" - taskid: c1588b1d-ab8e-4e55-8f47-b705c51cf5bb + taskid: 12b55740-45fd-4d84-88e0-ddfe4149352d type: regular task: - id: c1588b1d-ab8e-4e55-8f47-b705c51cf5bb + id: 12b55740-45fd-4d84-88e0-ddfe4149352d version: -1 name: Group Rule List description: Retrieves a list of the rule groups. @@ -729,7 +729,7 @@ tasks: { "position": { "x": 265, - "y": 2995 + "y": 3170 } } note: false @@ -741,10 +741,10 @@ tasks: isautoswitchedtoquietmode: false "18": id: "18" - taskid: 478e63c4-6b7d-42e3-82d7-aaebc06140cb + taskid: 2681e4d2-b32b-4737-801d-c628eef7d316 type: condition task: - id: 478e63c4-6b7d-42e3-82d7-aaebc06140cb + id: 2681e4d2-b32b-4737-801d-c628eef7d316 version: -1 name: Validate Outputs type: condition @@ -794,7 +794,7 @@ tasks: { "position": { "x": 265, - "y": 3170 + "y": 3345 } } note: false @@ -806,10 +806,10 @@ tasks: isautoswitchedtoquietmode: false "19": id: "19" - taskid: 701783b3-d734-4580-8479-4e4f2a397e8e + taskid: da4a1873-4ee6-45c8-82b2-9e6693d28b8e type: regular task: - id: 701783b3-d734-4580-8479-4e4f2a397e8e + id: da4a1873-4ee6-45c8-82b2-9e6693d28b8e version: -1 name: Assets List description: Retrieves assets list. @@ -829,7 +829,7 @@ tasks: { "position": { "x": 265, - "y": 3345 + "y": 3520 } } note: false @@ -841,10 +841,10 @@ tasks: isautoswitchedtoquietmode: false "20": id: "20" - taskid: 93a4456e-943f-46ec-8eb2-baf40646c28b + taskid: 24596580-9b2a-4951-8bb3-066e3fd15178 type: condition task: - id: 93a4456e-943f-46ec-8eb2-baf40646c28b + id: 24596580-9b2a-4951-8bb3-066e3fd15178 version: -1 name: Validate Outputs type: condition @@ -878,7 +878,7 @@ tasks: { "position": { "x": 265, - "y": 3520 + "y": 3695 } } note: false @@ -890,10 +890,10 @@ tasks: isautoswitchedtoquietmode: false "21": id: "21" - taskid: 28fd0dab-a5b7-42d2-82e4-258937e99cd5 + taskid: f245b0a0-5c98-4213-83ca-5e4d2052f711 type: regular task: - id: 28fd0dab-a5b7-42d2-82e4-258937e99cd5 + id: f245b0a0-5c98-4213-83ca-5e4d2052f711 version: -1 name: Create Reference Set description: Create a new reference set. @@ -919,7 +919,7 @@ tasks: { "position": { "x": 265, - "y": 3695 + "y": 3870 } } note: false @@ -931,10 +931,10 @@ tasks: isautoswitchedtoquietmode: false "22": id: "22" - taskid: b42f76c2-30a2-449b-8f21-c918836d8fa1 + taskid: 7504a24c-8588-410f-8750-4dbb536a1473 type: condition task: - id: b42f76c2-30a2-449b-8f21-c918836d8fa1 + id: 7504a24c-8588-410f-8750-4dbb536a1473 version: -1 name: Validate Outputs type: condition @@ -992,7 +992,7 @@ tasks: { "position": { "x": 265, - "y": 3870 + "y": 4045 } } note: false @@ -1004,10 +1004,10 @@ tasks: isautoswitchedtoquietmode: false "23": id: "23" - taskid: 07331bf8-a960-4745-8a06-48b8b4232f97 + taskid: defbc33f-b7c8-4b10-8919-bb098259821e type: regular task: - id: 07331bf8-a960-4745-8a06-48b8b4232f97 + id: defbc33f-b7c8-4b10-8919-bb098259821e version: -1 name: Get Reference Details description: Retrieve a list of reference sets. @@ -1027,7 +1027,7 @@ tasks: { "position": { "x": 265, - "y": 5445 + "y": 5620 } } note: false @@ -1039,10 +1039,10 @@ tasks: isautoswitchedtoquietmode: false "25": id: "25" - taskid: 35d6b65e-6c66-4b56-820e-3221fc62b44a + taskid: 69da809d-5cbe-4270-8aac-abecc99151a1 type: regular task: - id: 35d6b65e-6c66-4b56-820e-3221fc62b44a + id: 69da809d-5cbe-4270-8aac-abecc99151a1 version: -1 name: Delete Context description: Delete field from context @@ -1064,7 +1064,7 @@ tasks: { "position": { "x": 265, - "y": 4045 + "y": 4220 } } note: false @@ -1076,10 +1076,10 @@ tasks: isautoswitchedtoquietmode: false "26": id: "26" - taskid: 3ee72307-8dd0-4ab1-8923-96689e7b92d5 + taskid: 77dc530e-1e4b-4a5b-8362-cc0fde5bb1f1 type: regular task: - id: 3ee72307-8dd0-4ab1-8923-96689e7b92d5 + id: 77dc530e-1e4b-4a5b-8362-cc0fde5bb1f1 version: -1 name: Add Value To Reference description: Add or update an element in a reference set. @@ -1103,7 +1103,7 @@ tasks: { "position": { "x": 265, - "y": 4920 + "y": 5095 } } note: false @@ -1115,10 +1115,10 @@ tasks: isautoswitchedtoquietmode: false "27": id: "27" - taskid: bfaf2d7c-bf76-415b-8986-23cf81ea3a9b + taskid: 0cb8977c-178a-4d44-847c-61a7cf65a714 type: condition task: - id: bfaf2d7c-bf76-415b-8986-23cf81ea3a9b + id: 0cb8977c-178a-4d44-847c-61a7cf65a714 version: -1 name: Validate Outputs, With New Element Count type: condition @@ -1168,7 +1168,7 @@ tasks: { "position": { "x": 265, - "y": 5620 + "y": 5795 } } note: false @@ -1180,10 +1180,10 @@ tasks: isautoswitchedtoquietmode: false "28": id: "28" - taskid: e925c4ef-3213-4bfe-82aa-ba3ee7e8c0b1 + taskid: 4cf5bc10-2477-49d4-8a1c-44a90d21c0b9 type: regular task: - id: e925c4ef-3213-4bfe-82aa-ba3ee7e8c0b1 + id: 4cf5bc10-2477-49d4-8a1c-44a90d21c0b9 version: -1 name: Delete Context description: Delete field from context @@ -1205,7 +1205,7 @@ tasks: { "position": { "x": 265, - "y": 5270 + "y": 5445 } } note: false @@ -1217,10 +1217,10 @@ tasks: isautoswitchedtoquietmode: false "29": id: "29" - taskid: 08d48151-c602-49a2-8e31-89b179d21ba8 + taskid: 2c6423b7-4b50-45e3-86fc-2b3086142d7c type: regular task: - id: 08d48151-c602-49a2-8e31-89b179d21ba8 + id: 2c6423b7-4b50-45e3-86fc-2b3086142d7c version: -1 name: Delete Reference Set Value description: Remove a value from a reference set. @@ -1244,7 +1244,7 @@ tasks: { "position": { "x": 265, - "y": 5795 + "y": 5970 } } note: false @@ -1256,10 +1256,10 @@ tasks: isautoswitchedtoquietmode: false "30": id: "30" - taskid: 70059596-df9e-449f-8eec-1e1590c5c7d8 + taskid: ddcf9895-4b40-4d78-86df-3b4a2d26169a type: regular task: - id: 70059596-df9e-449f-8eec-1e1590c5c7d8 + id: ddcf9895-4b40-4d78-86df-3b4a2d26169a version: -1 name: Delete Context description: Delete field from context @@ -1281,7 +1281,7 @@ tasks: { "position": { "x": 265, - "y": 5970 + "y": 6145 } } note: false @@ -1293,10 +1293,10 @@ tasks: isautoswitchedtoquietmode: false "31": id: "31" - taskid: 24e02516-26dd-427b-8387-cb2fecbab6df + taskid: f6f7a4c4-f8de-466e-8638-d69924faee41 type: regular task: - id: 24e02516-26dd-427b-8387-cb2fecbab6df + id: f6f7a4c4-f8de-466e-8638-d69924faee41 version: -1 name: Get Reference With The Deleted Value description: Retrieve a list of reference sets. @@ -1316,7 +1316,7 @@ tasks: { "position": { "x": 265, - "y": 6145 + "y": 6320 } } note: false @@ -1328,10 +1328,10 @@ tasks: isautoswitchedtoquietmode: false "32": id: "32" - taskid: 09f6eed5-414f-4da3-8d86-d3575021a5bb + taskid: e8c9fed6-a10f-451c-8bbe-eb4ab20172ad type: condition task: - id: 09f6eed5-414f-4da3-8d86-d3575021a5bb + id: e8c9fed6-a10f-451c-8bbe-eb4ab20172ad version: -1 name: Validate Outputs, Validate Element Count Decreased type: condition @@ -1357,7 +1357,7 @@ tasks: { "position": { "x": 265, - "y": 6320 + "y": 6495 } } note: false @@ -1369,10 +1369,10 @@ tasks: isautoswitchedtoquietmode: false "33": id: "33" - taskid: 2477e3f4-10fa-4e8d-8dd6-830b00bf87a9 + taskid: 8a7be1f2-20fb-4937-82d4-d97e5764d87e type: regular task: - id: 2477e3f4-10fa-4e8d-8dd6-830b00bf87a9 + id: 8a7be1f2-20fb-4937-82d4-d97e5764d87e version: -1 name: Delete Reference Set description: Removes a reference set or purges its contents. @@ -1392,7 +1392,7 @@ tasks: { "position": { "x": 265, - "y": 6495 + "y": 6670 } } note: false @@ -1404,10 +1404,10 @@ tasks: isautoswitchedtoquietmode: false "34": id: "34" - taskid: 7cda6c6a-414a-4907-8956-562a6e65cdce + taskid: a04680af-358a-49c2-8f81-7f57b259fb62 type: regular task: - id: 7cda6c6a-414a-4907-8956-562a6e65cdce + id: a04680af-358a-49c2-8f81-7f57b259fb62 version: -1 name: Get Domains List description: Gets the list of domains. You must have the System Administrator or Security Administrator permissions to call this endpoint if you are trying to retrieve the details of all domains. You can retrieve details of domains that are assigned to your Security Profile without having the System Administrator or Security Administrator permissions. If you do not have the System Administrator or Security Administrator permissions, then for each domain assigned to your security profile you can only view the values for the id and name fields. All other values return null. @@ -1424,7 +1424,7 @@ tasks: { "position": { "x": 265, - "y": 6670 + "y": 6845 } } note: false @@ -1436,10 +1436,10 @@ tasks: isautoswitchedtoquietmode: false "35": id: "35" - taskid: 9e030fc5-06ba-4552-83ec-3df2e4e729a8 + taskid: 6db6ef28-6334-4171-8e51-dfe7f1569ecc type: condition task: - id: 9e030fc5-06ba-4552-83ec-3df2e4e729a8 + id: 6db6ef28-6334-4171-8e51-dfe7f1569ecc version: -1 name: Validate Outputs type: condition @@ -1465,7 +1465,7 @@ tasks: { "position": { "x": 265, - "y": 6845 + "y": 7020 } } note: false @@ -1477,10 +1477,10 @@ tasks: isautoswitchedtoquietmode: false "36": id: "36" - taskid: 83b10f17-2d0c-4b88-8555-28a1ba1d6d06 + taskid: 5b2c6621-6472-4ed1-8c12-2ecb67aebb4d type: regular task: - id: 83b10f17-2d0c-4b88-8555-28a1ba1d6d06 + id: 5b2c6621-6472-4ed1-8c12-2ecb67aebb4d version: -1 name: Geolocations For IPs description: Retrieves the MaxMind geoip data for the given IP address. @@ -1502,7 +1502,7 @@ tasks: { "position": { "x": 265, - "y": 7020 + "y": 7195 } } note: false @@ -1514,10 +1514,10 @@ tasks: isautoswitchedtoquietmode: false "37": id: "37" - taskid: 34409f2c-9686-42c2-8fdc-09b6767c3013 + taskid: 6dcd1544-8853-472c-89ff-e0a54e983a98 type: condition task: - id: 34409f2c-9686-42c2-8fdc-09b6767c3013 + id: 6dcd1544-8853-472c-89ff-e0a54e983a98 version: -1 name: Validate Outputs type: condition @@ -1599,7 +1599,7 @@ tasks: { "position": { "x": 265, - "y": 7195 + "y": 7370 } } note: false @@ -1611,10 +1611,10 @@ tasks: isautoswitchedtoquietmode: false "38": id: "38" - taskid: 1b7dbcd7-2242-44ba-81b3-d0da446e6619 + taskid: c4a09a0b-b9af-4470-89ef-fd12bea72e6b type: regular task: - id: 1b7dbcd7-2242-44ba-81b3-d0da446e6619 + id: c4a09a0b-b9af-4470-89ef-fd12bea72e6b version: -1 name: Sources List description: Retrieves a list of log sources. @@ -1636,7 +1636,7 @@ tasks: { "position": { "x": 265, - "y": 7370 + "y": 7545 } } note: false @@ -1648,10 +1648,10 @@ tasks: isautoswitchedtoquietmode: false "39": id: "39" - taskid: eb1ebb8a-9aba-4fde-8108-a5c5139a5864 + taskid: 451f124e-979f-4b6b-8bcc-bd15f21b5d0d type: condition task: - id: eb1ebb8a-9aba-4fde-8108-a5c5139a5864 + id: 451f124e-979f-4b6b-8bcc-bd15f21b5d0d version: -1 name: Validate Outputs type: condition @@ -1703,7 +1703,7 @@ tasks: { "position": { "x": 265, - "y": 7545 + "y": 7720 } } note: false @@ -1715,10 +1715,10 @@ tasks: isautoswitchedtoquietmode: false "40": id: "40" - taskid: ebe6fb74-cf0c-4fcd-826e-eeec124c59dd + taskid: 51f9a9ef-133d-491e-8bd2-fb3e1648f8eb type: regular task: - id: ebe6fb74-cf0c-4fcd-826e-eeec124c59dd + id: 51f9a9ef-133d-491e-8bd2-fb3e1648f8eb version: -1 name: Custom Properties description: Retrieves a list of event regex properties. @@ -1738,7 +1738,7 @@ tasks: { "position": { "x": 265, - "y": 7720 + "y": 7895 } } note: false @@ -1750,10 +1750,10 @@ tasks: isautoswitchedtoquietmode: false "41": id: "41" - taskid: 7a2bbfe2-cc08-46ac-8e65-cf0b043e066d + taskid: 3800ef6d-e061-448d-8f47-775f21ac00f2 type: condition task: - id: 7a2bbfe2-cc08-46ac-8e65-cf0b043e066d + id: 3800ef6d-e061-448d-8f47-775f21ac00f2 version: -1 name: Validate Outputs type: condition @@ -1795,7 +1795,7 @@ tasks: { "position": { "x": 265, - "y": 7895 + "y": 8070 } } note: false @@ -1807,10 +1807,10 @@ tasks: isautoswitchedtoquietmode: false "43": id: "43" - taskid: 51638b74-ed2e-4538-8b08-a5515fe9cd3f + taskid: 88d4399d-64fa-43c8-84f2-ebe0b6e3f13f type: regular task: - id: 51638b74-ed2e-4538-8b08-a5515fe9cd3f + id: 88d4399d-64fa-43c8-84f2-ebe0b6e3f13f version: -1 name: Get Saved Searches description: Retrieves a list of Ariel saved searches. @@ -1830,7 +1830,7 @@ tasks: { "position": { "x": 265, - "y": 8070 + "y": 8245 } } note: false @@ -1842,10 +1842,10 @@ tasks: isautoswitchedtoquietmode: false "44": id: "44" - taskid: 68f155ef-7064-49f5-8652-861c0640752d + taskid: 7393c923-6007-4bc7-8879-49edede874af type: regular task: - id: 68f155ef-7064-49f5-8652-861c0640752d + id: 7393c923-6007-4bc7-8879-49edede874af version: -1 name: Get Search IDs description: Retrieves the list of Ariel searches IDs. Search status and results can be polled by sending search ID to 'qradar-search-status-get' and 'qradar-search-results-get' commands. @@ -1865,7 +1865,7 @@ tasks: { "position": { "x": 265, - "y": 8245 + "y": 8420 } } note: false @@ -1877,10 +1877,10 @@ tasks: isautoswitchedtoquietmode: false "46": id: "46" - taskid: 4ed418cd-4b52-4375-8b3e-be377997f756 + taskid: f9624038-63c9-46ef-8c80-ce254e79e9cb type: regular task: - id: 4ed418cd-4b52-4375-8b3e-be377997f756 + id: f9624038-63c9-46ef-8c80-ce254e79e9cb version: -1 name: Get Source IPs description: Get Source IPs @@ -1900,7 +1900,7 @@ tasks: { "position": { "x": 265, - "y": 8595 + "y": 8770 } } note: false @@ -1912,10 +1912,10 @@ tasks: isautoswitchedtoquietmode: false "47": id: "47" - taskid: f8e7d42f-0369-4075-8980-8d9a28b9fd3e + taskid: c5a7b0b7-2524-40a3-8b1e-d057777c9855 type: condition task: - id: f8e7d42f-0369-4075-8980-8d9a28b9fd3e + id: c5a7b0b7-2524-40a3-8b1e-d057777c9855 version: -1 name: Does Results Exists type: condition @@ -1938,7 +1938,7 @@ tasks: { "position": { "x": 265, - "y": 8770 + "y": 8945 } } note: false @@ -1950,10 +1950,10 @@ tasks: isautoswitchedtoquietmode: false "48": id: "48" - taskid: f213d35c-9034-40d0-8dd4-a43c80665862 + taskid: 7538bd6a-0e26-4f03-8bb6-4410d536a983 type: regular task: - id: f213d35c-9034-40d0-8dd4-a43c80665862 + id: 7538bd6a-0e26-4f03-8bb6-4410d536a983 version: -1 name: Get Local Destination IPs description: Get Source IPs @@ -1973,7 +1973,7 @@ tasks: { "position": { "x": 265, - "y": 8945 + "y": 9120 } } note: false @@ -1985,10 +1985,10 @@ tasks: isautoswitchedtoquietmode: false "49": id: "49" - taskid: 9e8951b1-0b73-4d62-8cd8-3be5b7146668 + taskid: 58b27563-daeb-4e4b-81a2-500c80f9a7dc type: condition task: - id: 9e8951b1-0b73-4d62-8cd8-3be5b7146668 + id: 58b27563-daeb-4e4b-81a2-500c80f9a7dc version: -1 name: Does Results Exists type: condition @@ -2011,7 +2011,7 @@ tasks: { "position": { "x": 265, - "y": 9120 + "y": 9295 } } note: false @@ -2023,10 +2023,10 @@ tasks: isautoswitchedtoquietmode: false "52": id: "52" - taskid: 732b9a9f-6418-4ae7-89c6-69cc5d022602 + taskid: 1a950542-bde6-4f5c-89c3-6f97a9db0e93 type: regular task: - id: 732b9a9f-6418-4ae7-89c6-69cc5d022602 + id: 1a950542-bde6-4f5c-89c3-6f97a9db0e93 version: -1 name: DeleteContext description: Delete field from context @@ -2048,7 +2048,7 @@ tasks: { "position": { "x": 265, - "y": 4745 + "y": 4920 } } note: false @@ -2060,10 +2060,10 @@ tasks: isautoswitchedtoquietmode: false "60": id: "60" - taskid: 46855953-d7b8-49af-8405-4738ca3e6c9a + taskid: c1ff48d6-9d07-4ee2-8509-b9cab14640d6 type: regular task: - id: 46855953-d7b8-49af-8405-4738ca3e6c9a + id: c1ff48d6-9d07-4ee2-8509-b9cab14640d6 version: -1 name: 'create reference set with #' description: Creates a new reference set. @@ -2089,7 +2089,7 @@ tasks: { "position": { "x": 265, - "y": 4220 + "y": 4395 } } note: false @@ -2101,10 +2101,10 @@ tasks: isautoswitchedtoquietmode: false "61": id: "61" - taskid: c4a0e02d-cffb-437c-8422-aae63e433cd6 + taskid: 065474b9-8a9c-4f31-8c60-cb060b7e7753 type: regular task: - id: c4a0e02d-cffb-437c-8422-aae63e433cd6 + id: 065474b9-8a9c-4f31-8c60-cb060b7e7753 version: -1 name: 'set value to reference set that contains #' description: Adds or updates an element in a reference set. @@ -2126,7 +2126,7 @@ tasks: { "position": { "x": 265, - "y": 4395 + "y": 4570 } } note: false @@ -2138,10 +2138,10 @@ tasks: isautoswitchedtoquietmode: false "62": id: "62" - taskid: ef490bf0-b7d2-42bc-88bc-8b14c97e50e0 + taskid: 9cddea2c-0234-4b3e-815b-3aae11d74cbe type: regular task: - id: ef490bf0-b7d2-42bc-88bc-8b14c97e50e0 + id: 9cddea2c-0234-4b3e-815b-3aae11d74cbe version: -1 name: 'delete reference set with #' description: Removes a reference set or purges its contents. @@ -2161,7 +2161,7 @@ tasks: { "position": { "x": 265, - "y": 4570 + "y": 4745 } } note: false @@ -2173,12 +2173,12 @@ tasks: isautoswitchedtoquietmode: false "63": id: "63" - taskid: 3982c03e-57c7-4f0b-8beb-46c209514f78 + taskid: c667dbd9-b588-4cf4-84ab-1d36bd5dd943 type: regular task: - id: 3982c03e-57c7-4f0b-8beb-46c209514f78 + id: c667dbd9-b588-4cf4-84ab-1d36bd5dd943 version: -1 - name: Get events with polling + name: Get events with polling custom query description: Polling command to search for events of a specific offense. script: '|||qradar-search-retrieve-events' type: regular @@ -2188,15 +2188,15 @@ tasks: '#none#': - "64" scriptarguments: - offense_id: - simple: ${inputs.offense_id} + query_expression: + simple: SELECT * FROM events WHERE severity >= 5 limit 1 separatecontext: false continueonerrortype: "" view: |- { "position": { "x": 265, - "y": 9295 + "y": 9470 } } note: false @@ -2208,10 +2208,10 @@ tasks: isautoswitchedtoquietmode: false "64": id: "64" - taskid: e7401796-e0d1-4115-80c9-09235aae457e + taskid: 09024500-cd55-45cb-8eb6-49a8d5517f7e type: condition task: - id: e7401796-e0d1-4115-80c9-09235aae457e + id: 09024500-cd55-45cb-8eb6-49a8d5517f7e version: -1 name: Validate polling type: condition @@ -2219,7 +2219,7 @@ tasks: brand: "" nexttasks: "yes": - - "67" + - "68" separatecontext: false conditions: - label: "yes" @@ -2241,7 +2241,7 @@ tasks: { "position": { "x": 265, - "y": 9470 + "y": 9645 } } note: false @@ -2253,12 +2253,12 @@ tasks: isautoswitchedtoquietmode: false "65": id: "65" - taskid: eef4905f-e83f-45bf-8b40-d1e38d97977f + taskid: 74f87781-7ee4-43fb-8fd3-85b5a4179ed5 type: regular task: - id: eef4905f-e83f-45bf-8b40-d1e38d97977f + id: 74f87781-7ee4-43fb-8fd3-85b5a4179ed5 version: -1 - name: get events with polling custom query + name: Get offense with polling description: Polling command to search for events of a specific offense. script: '|||qradar-search-retrieve-events' type: regular @@ -2266,103 +2266,17 @@ tasks: brand: "" nexttasks: '#none#': - - "66" - scriptarguments: - query_expression: - simple: SELECT * FROM events WHERE INOFFENSE(${inputs.offense_id}) limit 3 - start 3600000 - separatecontext: false - continueonerrortype: "" - view: |- - { - "position": { - "x": 265, - "y": 9820 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 - isoversize: false - isautoswitchedtoquietmode: false - "66": - id: "66" - taskid: a596ea4b-0b0d-42d9-8559-f7f2efcc8d59 - type: condition - task: - id: a596ea4b-0b0d-42d9-8559-f7f2efcc8d59 - version: -1 - name: Validate polling - type: condition - iscommand: false - brand: "" - nexttasks: - "yes": - - "68" - separatecontext: false - conditions: - - label: "yes" - condition: - - - operator: isNotEmpty - left: - value: - simple: QRadar.SearchEvents.ID - iscontext: true - right: - value: {} - - - operator: isNotEmpty - left: - value: - simple: QRadar.SearchEvents.Events - iscontext: true - continueonerrortype: "" - view: |- - { - "position": { - "x": 265, - "y": 9995 - } - } - note: false - timertriggers: [] - ignoreworker: false - skipunavailable: false - quietmode: 0 - isoversize: false - isautoswitchedtoquietmode: false - "67": - id: "67" - taskid: afc7323e-1454-46c9-80af-012c3bd1618e - type: regular - task: - id: afc7323e-1454-46c9-80af-012c3bd1618e - version: -1 - name: Delete Context - description: |- - Delete field from context. - - This automation runs using the default Limited User role, unless you explicitly change the permissions. - For more information, see the section about permissions here: - https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.10/Cortex-XSOAR-Administrator-Guide/Automations - scriptName: DeleteContext - type: regular - iscommand: false - brand: "" - nexttasks: - '#none#': - - "65" + - "76" scriptarguments: - all: - simple: "yes" + offense_id: + simple: ${QRadar.Offense.[0].ID} separatecontext: false continueonerrortype: "" view: |- { "position": { "x": 265, - "y": 9645 + "y": 1070 } } note: false @@ -2374,10 +2288,10 @@ tasks: isautoswitchedtoquietmode: false "68": id: "68" - taskid: 43c8a023-b2d2-4cd4-8390-7ad84367e89d + taskid: f21eb13e-9517-4541-82bd-9a5169a10870 type: regular task: - id: 43c8a023-b2d2-4cd4-8390-7ad84367e89d + id: f21eb13e-9517-4541-82bd-9a5169a10870 version: -1 name: Delete Context description: |- @@ -2402,7 +2316,7 @@ tasks: { "position": { "x": 265, - "y": 10170 + "y": 9820 } } note: false @@ -2414,10 +2328,10 @@ tasks: isautoswitchedtoquietmode: false "69": id: "69" - taskid: f11ee798-2d93-4aec-8548-4a069c078238 + taskid: 97c3f8a7-9a99-4a63-8c2e-31e166373e6f type: regular task: - id: f11ee798-2d93-4aec-8548-4a069c078238 + id: 97c3f8a7-9a99-4a63-8c2e-31e166373e6f version: -1 name: Create Remote network cidrs description: Create remote network cidrs @@ -2443,7 +2357,7 @@ tasks: { "position": { "x": 265, - "y": 11045 + "y": 10695 } } note: false @@ -2455,10 +2369,10 @@ tasks: isautoswitchedtoquietmode: false "70": id: "70" - taskid: 58dd14c9-8321-485f-8ca2-a8201f22fc55 + taskid: 3adda86c-9006-4709-8fe7-9d9f76dd2259 type: regular task: - id: 58dd14c9-8321-485f-8ca2-a8201f22fc55 + id: 3adda86c-9006-4709-8fe7-9d9f76dd2259 version: -1 name: Remote network cidrs List description: Retrieves the list of staged remote networks. @@ -2480,7 +2394,7 @@ tasks: { "position": { "x": 265, - "y": 11220 + "y": 10870 } } note: false @@ -2492,10 +2406,10 @@ tasks: isautoswitchedtoquietmode: false "71": id: "71" - taskid: 864bc884-7b3f-4676-84e8-564abe301bc4 + taskid: 485b708f-a9a3-4a90-8bf6-e8f1312edb63 type: condition task: - id: 864bc884-7b3f-4676-84e8-564abe301bc4 + id: 485b708f-a9a3-4a90-8bf6-e8f1312edb63 version: -1 name: Validate Outputs type: condition @@ -2521,7 +2435,7 @@ tasks: { "position": { "x": 265, - "y": 11395 + "y": 11045 } } note: false @@ -2533,10 +2447,10 @@ tasks: isautoswitchedtoquietmode: false "72": id: "72" - taskid: d36f20f1-438f-4f0d-8add-52a056699c04 + taskid: 7b1ffc12-4262-47b7-8cfe-47e260c0ff83 type: regular task: - id: d36f20f1-438f-4f0d-8add-52a056699c04 + id: 7b1ffc12-4262-47b7-8cfe-47e260c0ff83 version: -1 name: Update Remote network cidrs description: Updates an existing staged remote network. @@ -2564,7 +2478,7 @@ tasks: { "position": { "x": 265, - "y": 12620 + "y": 12270 } } note: false @@ -2576,10 +2490,10 @@ tasks: isautoswitchedtoquietmode: false "73": id: "73" - taskid: 4a8d9fd1-9109-4eba-8f19-bcbb911ee09f + taskid: 9892abd5-d16f-4cfc-8082-baece298a9f3 type: condition task: - id: 4a8d9fd1-9109-4eba-8f19-bcbb911ee09f + id: 9892abd5-d16f-4cfc-8082-baece298a9f3 version: -1 name: Validate Outputs type: condition @@ -2621,7 +2535,7 @@ tasks: { "position": { "x": 265, - "y": 12795 + "y": 12445 } } note: false @@ -2633,10 +2547,10 @@ tasks: isautoswitchedtoquietmode: false "74": id: "74" - taskid: 4040e052-eee0-479d-8fca-eccbb795f762 + taskid: 82ecdc43-e078-48ec-8b94-6f88ad263425 type: regular task: - id: 4040e052-eee0-479d-8fca-eccbb795f762 + id: 82ecdc43-e078-48ec-8b94-6f88ad263425 version: -1 name: Delete Remote network cidrs description: Deletes an existing staged remote network. @@ -2656,7 +2570,7 @@ tasks: { "position": { "x": 265, - "y": 12970 + "y": 12620 } } note: false @@ -2668,10 +2582,10 @@ tasks: isautoswitchedtoquietmode: false "75": id: "75" - taskid: 4763d0ce-7871-45ce-83ba-c13797499227 + taskid: 55a0de06-3397-4c44-83de-30e221fb3207 type: regular task: - id: 4763d0ce-7871-45ce-83ba-c13797499227 + id: 55a0de06-3397-4c44-83de-30e221fb3207 version: -1 name: Write ID description: Set a value in context under the key you entered. @@ -2709,10 +2623,10 @@ tasks: isautoswitchedtoquietmode: false "76": id: "76" - taskid: 769e7cda-593e-4e49-824f-4b7889441852 + taskid: 4a3159e8-ca96-496b-8b4c-33646aa480d3 type: regular task: - id: 769e7cda-593e-4e49-824f-4b7889441852 + id: 4a3159e8-ca96-496b-8b4c-33646aa480d3 version: -1 name: DeleteContext description: |- @@ -2739,7 +2653,7 @@ tasks: { "position": { "x": 265, - "y": 1070 + "y": 1245 } } note: false @@ -2751,10 +2665,10 @@ tasks: isautoswitchedtoquietmode: false "78": id: "78" - taskid: dc204356-2c2f-4700-8f9e-a6a27dacd298 + taskid: e2b2b7ef-fa5d-4b43-85f8-f6089dc89f4d type: regular task: - id: dc204356-2c2f-4700-8f9e-a6a27dacd298 + id: e2b2b7ef-fa5d-4b43-85f8-f6089dc89f4d version: -1 name: Delete Reference Set description: Removes a reference set or purges its contents. @@ -2787,10 +2701,10 @@ tasks: isautoswitchedtoquietmode: false "79": id: "79" - taskid: 02fa9478-c09f-4b87-8175-179ae4a6cc3d + taskid: d4afc0b0-54d9-410e-8022-f49ad7dfdf58 type: regular task: - id: 02fa9478-c09f-4b87-8175-179ae4a6cc3d + id: d4afc0b0-54d9-410e-8022-f49ad7dfdf58 version: -1 name: 'delete reference set with #' description: Removes a reference set or purges its contents. @@ -2823,10 +2737,10 @@ tasks: isautoswitchedtoquietmode: false "81": id: "81" - taskid: e1c62169-5167-4fd6-8791-1dbe1d5b67ec + taskid: 574b2111-b45f-417f-8b6c-942dd7d55c48 type: regular task: - id: e1c62169-5167-4fd6-8791-1dbe1d5b67ec + id: 574b2111-b45f-417f-8b6c-942dd7d55c48 version: -1 name: Find old cidr description: Retrieves the list of staged remote networks. @@ -2846,7 +2760,7 @@ tasks: { "position": { "x": 265, - "y": 10345 + "y": 9995 } } note: false @@ -2858,10 +2772,10 @@ tasks: isautoswitchedtoquietmode: false "82": id: "82" - taskid: 51b39265-e01b-45e0-84b4-c8b5e4f11676 + taskid: bc2fe767-0c68-48f5-8fc8-03297c0eeff3 type: condition task: - id: 51b39265-e01b-45e0-84b4-c8b5e4f11676 + id: bc2fe767-0c68-48f5-8fc8-03297c0eeff3 version: -1 name: If Exists type: condition @@ -2886,7 +2800,7 @@ tasks: { "position": { "x": 265, - "y": 10520 + "y": 10170 } } note: false @@ -2898,10 +2812,10 @@ tasks: isautoswitchedtoquietmode: false "83": id: "83" - taskid: becfb7fe-521f-4185-8462-6e7257b28562 + taskid: 69bffcc7-6288-478b-817d-cba5faf22965 type: regular task: - id: becfb7fe-521f-4185-8462-6e7257b28562 + id: 69bffcc7-6288-478b-817d-cba5faf22965 version: -1 name: Delete old cidr description: Deletes an existing staged remote network. @@ -2921,7 +2835,7 @@ tasks: { "position": { "x": 377.5, - "y": 10695 + "y": 10345 } } note: false @@ -2933,10 +2847,10 @@ tasks: isautoswitchedtoquietmode: false "84": id: "84" - taskid: 76c622ba-7ee2-4843-8952-53f99cf72a80 + taskid: 48675951-93ee-444b-8523-9a08a117e48f type: regular task: - id: 76c622ba-7ee2-4843-8952-53f99cf72a80 + id: 48675951-93ee-444b-8523-9a08a117e48f version: -1 name: Delete Context description: |- @@ -2961,7 +2875,7 @@ tasks: { "position": { "x": 377.5, - "y": 10870 + "y": 10520 } } note: false @@ -2973,10 +2887,10 @@ tasks: isautoswitchedtoquietmode: false "85": id: "85" - taskid: 730d4678-f23b-4da6-8ad0-b97926c7188b + taskid: 608e8d54-e135-4fab-85ea-ee14c52c8f87 type: regular task: - id: 730d4678-f23b-4da6-8ad0-b97926c7188b + id: 608e8d54-e135-4fab-85ea-ee14c52c8f87 version: -1 name: Find old cidr description: Retrieves the list of staged remote networks. @@ -2996,7 +2910,7 @@ tasks: { "position": { "x": 265, - "y": 11920 + "y": 11570 } } note: false @@ -3008,10 +2922,10 @@ tasks: isautoswitchedtoquietmode: false "86": id: "86" - taskid: f33e8dce-8cf8-4015-853a-50b84c3f377b + taskid: 49ac02b7-5dea-4673-88b7-dd37f16b2961 type: condition task: - id: f33e8dce-8cf8-4015-853a-50b84c3f377b + id: 49ac02b7-5dea-4673-88b7-dd37f16b2961 version: -1 name: If Exists type: condition @@ -3036,7 +2950,7 @@ tasks: { "position": { "x": 265, - "y": 12095 + "y": 11745 } } note: false @@ -3048,10 +2962,10 @@ tasks: isautoswitchedtoquietmode: false "87": id: "87" - taskid: 7c8fbc45-2554-4118-8e2a-88de5a61a20e + taskid: 1195f5f8-755e-43ca-89a8-ef81eb612bd3 type: regular task: - id: 7c8fbc45-2554-4118-8e2a-88de5a61a20e + id: 1195f5f8-755e-43ca-89a8-ef81eb612bd3 version: -1 name: Delete old cidr description: Deletes an existing staged remote network. @@ -3071,7 +2985,7 @@ tasks: { "position": { "x": 377.5, - "y": 12270 + "y": 11920 } } note: false @@ -3083,10 +2997,10 @@ tasks: isautoswitchedtoquietmode: false "88": id: "88" - taskid: cd6e32e5-aeda-401a-833a-a68671e68b3e + taskid: 34a7ca7c-079f-4522-895f-09f5f63c8952 type: regular task: - id: cd6e32e5-aeda-401a-833a-a68671e68b3e + id: 34a7ca7c-079f-4522-895f-09f5f63c8952 version: -1 name: Delete Context description: |- @@ -3113,7 +3027,7 @@ tasks: { "position": { "x": 377.5, - "y": 12445 + "y": 12095 } } note: false @@ -3125,10 +3039,10 @@ tasks: isautoswitchedtoquietmode: false "89": id: "89" - taskid: 7f58fd9b-27f2-4487-8d50-7fc64483dd4e + taskid: 895968fa-173f-43bb-80ac-f56c13746392 type: regular task: - id: 7f58fd9b-27f2-4487-8d50-7fc64483dd4e + id: 895968fa-173f-43bb-80ac-f56c13746392 version: -1 name: WriteID description: Set a value in context under the key you entered. @@ -3150,7 +3064,7 @@ tasks: { "position": { "x": 265, - "y": 11570 + "y": 11220 } } note: false @@ -3162,10 +3076,10 @@ tasks: isautoswitchedtoquietmode: false "90": id: "90" - taskid: 333d6486-b04d-467c-8bee-4eeb4568b74a + taskid: 30b76136-423f-485a-81f6-bd41803c558b type: regular task: - id: 333d6486-b04d-467c-8bee-4eeb4568b74a + id: 30b76136-423f-485a-81f6-bd41803c558b version: -1 name: DeleteContext description: |- @@ -3192,7 +3106,7 @@ tasks: { "position": { "x": 265, - "y": 11745 + "y": 11395 } } note: false @@ -3204,10 +3118,10 @@ tasks: isautoswitchedtoquietmode: false "91": id: "91" - taskid: 142ccee3-7c9c-460b-851b-78bebc3d0955 + taskid: bbe01867-7c46-42ac-8409-209b5c257c41 type: regular task: - id: 142ccee3-7c9c-460b-851b-78bebc3d0955 + id: bbe01867-7c46-42ac-8409-209b5c257c41 version: -1 name: Add Values To Reference description: Add or update an element in a reference set. @@ -3231,7 +3145,7 @@ tasks: { "position": { "x": 265, - "y": 5095 + "y": 5270 } } note: false @@ -3243,10 +3157,10 @@ tasks: isautoswitchedtoquietmode: false "45": id: "45" - taskid: bd00c7ed-4e21-4b48-8c6f-75abb5d53433 + taskid: 1453c2a2-1d12-4e76-8390-0e278216be1c type: playbook task: - id: bd00c7ed-4e21-4b48-8c6f-75abb5d53433 + id: 1453c2a2-1d12-4e76-8390-0e278216be1c version: -1 name: QRadarFullSearch description: This playbook runs a QRadar query and return its results to the context. @@ -3285,7 +3199,7 @@ tasks: { "position": { "x": 265, - "y": 8420 + "y": 8595 } } note: false @@ -3302,19 +3216,13 @@ view: |- }, "paper": { "dimensions": { - "height": 13160, + "height": 12810, "width": 810, "x": 50, "y": 50 } } } -inputs: -- key: offense_id - value: - simple: "203" - required: false - description: "The offense_id to search for." - playbookInputQuery: null +inputs: [] outputs: [] fromversion: 5.0.0 From 04497457bce52db9430039aae4b971028fae7826 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 25 Feb 2024 15:01:38 +0200 Subject: [PATCH 079/272] [Marketplace Contribution] PAN-OS by Palo Alto Networks - Content Pack Update (#31985) (#33088) * "contribution update to pack "PAN-OS by Palo Alto Networks"" * Update Panorama.yml * Update Panorama.py * Update Panorama.yml * Update Panorama_test.py * Update Panorama.yml * Update Panorama.py * pre-commit * Update 2_1_21.md * Update 2_1_21.md * Apply suggestions from code review * rn * rn --------- Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: amkoppad <82898085+amkoppad@users.noreply.github.com> Co-authored-by: MLainer1 Co-authored-by: MLainer1 <93524335+MLainer1@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- .../PAN-OS/Integrations/Panorama/Panorama.py | 20 +++++++++++--- .../PAN-OS/Integrations/Panorama/Panorama.yml | 14 ++++------ .../Panorama/Panorama_description.md | 26 +++++++++---------- .../Integrations/Panorama/Panorama_test.py | 2 +- Packs/PAN-OS/ReleaseNotes/2_1_22.md | 7 +++++ Packs/PAN-OS/pack_metadata.json | 2 +- 6 files changed, 42 insertions(+), 29 deletions(-) create mode 100644 Packs/PAN-OS/ReleaseNotes/2_1_22.md diff --git a/Packs/PAN-OS/Integrations/Panorama/Panorama.py b/Packs/PAN-OS/Integrations/Panorama/Panorama.py index 1e668db4ae7b..748ad0582192 100644 --- a/Packs/PAN-OS/Integrations/Panorama/Panorama.py +++ b/Packs/PAN-OS/Integrations/Panorama/Panorama.py @@ -1,5 +1,7 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 + + from collections import defaultdict from dataclasses import dataclass, fields from types import SimpleNamespace @@ -11819,7 +11821,7 @@ def get_object( ) -def get_device_state(topology: Topology, target: str) -> dict: +def get_device_state(topology: Topology, target: str, filename: str = None) -> dict: """ Get the device state from the provided device target (serial number). Note that this will attempt to connect directly to the firewall as there is no way to get the device state for a firewall via Panorama. @@ -11827,8 +11829,13 @@ def get_device_state(topology: Topology, target: str) -> dict: :param topology: `Topology` instance !no-auto-argument :param target: String to filter to only show specific hostnames or serial numbers. """ + if not filename: + file_name = f"{target}_device_state.tar.gz" + else: + file_name = f"{target}_{filename}_device_state.tar.gz" + return fileResult( - filename=f"{target}_device_state.tar.gz", + filename=file_name, data=FirewallCommand.get_device_state(topology, target), file_type=EntryType.ENTRY_INFO_FILE ) @@ -11936,9 +11943,14 @@ def pan_os_get_running_config(args: dict): if args.get("target"): params["target"] = args.get("target") - + file_name_arg = args.get("filename") + target = args.get("target") + if file_name_arg != 'running_config' and file_name_arg and target: + file_name = target + '_' + file_name_arg + '_running_config' + else: + file_name = file_name_arg result = http_request(URL, 'POST', params=params, is_xml=True) - return fileResult("running_config", result) + return fileResult(file_name, result) def pan_os_get_merged_config(args: dict): diff --git a/Packs/PAN-OS/Integrations/Panorama/Panorama.yml b/Packs/PAN-OS/Integrations/Panorama/Panorama.yml index b4f78830a80f..77a4eaa1f716 100644 --- a/Packs/PAN-OS/Integrations/Panorama/Panorama.yml +++ b/Packs/PAN-OS/Integrations/Panorama/Panorama.yml @@ -5035,6 +5035,9 @@ script: - arguments: - description: The serial number of the device. name: target + - defaultValue: 'running_config' + description: Name of the file to save the configuration to. + name: filename description: Pull the running config file. name: pan-os-get-running-config - arguments: @@ -7157,7 +7160,6 @@ script: defaultValue: disable description: Enables assigning EDL to the anti-spyware profile under "DNS Signature Policies". name: pan-os-apply-dns-signature-policy - outputs: [] - arguments: [] description: Gets file-blocking best practices. name: pan-os-get-file-blocking-best-practice @@ -8434,6 +8436,8 @@ script: - description: Serial number of the device from which to fetch the device state. name: target required: true + - description: Name of the file for the state file to be saved. Default will use the hostname as the filename. + name: filename description: Get the device state from the provided device. Note; This will attempt to connect directly to the provided target to get the device state. If the IP address as reported in "show system info" is unreachable, this command will fail. name: pan-os-platform-get-device-state outputs: @@ -8672,7 +8676,6 @@ script: - reverse description: Creates a new NAT rule in a Panorama/firewall instance. name: pan-os-create-nat-rule - outputs: [] - arguments: - description: The name of the NAT rule to delete. Can be retrieved from the pan-os-list-nat-rules command. name: rulename @@ -8687,7 +8690,6 @@ script: - post-rulebase description: Deletes a NAT rule. name: pan-os-delete-nat-rule - outputs: [] - arguments: - description: The name of the NAT rule to edit. Can be retrieved from the pan-os-list-nat-rules command. name: rulename @@ -8739,7 +8741,6 @@ script: required: true description: Edits a NAT rule. name: pan-os-edit-nat-rule - outputs: [] - arguments: - description: The name of the virtual router to retrieve. If not mentioned, will bring all the virtual routers. name: virtual_router @@ -8893,7 +8894,6 @@ script: name: filter_bgp_extended_community description: Creates a new redistribution-profile under a virtual-router for a Panorama/firewall instance. name: pan-os-create-redistribution-profile - outputs: [] - arguments: - description: The name of the redistribution-profile to edit. name: name @@ -8933,7 +8933,6 @@ script: defaultValue: 'replace' description: Edits a redistribution-profile in a virtual-router. name: pan-os-edit-redistribution-profile - outputs: [] - arguments: - description: The name of the redistribution-profile to delete. name: name @@ -8945,7 +8944,6 @@ script: name: template description: Deletes a redistribution-profile from a virtual-router. name: pan-os-delete-redistribution-profile - outputs: [] - arguments: - description: The name of the pbf-rule to retrieve. If not mentioned, will bring all the pbf rules. name: rulename @@ -9117,7 +9115,6 @@ script: name: nexthop_address_list description: Creates a new policy-based-forwarding (PBF) rule in a Panorama/firewall instance. name: pan-os-create-pbf-rule - outputs: [] - arguments: - description: The name of the PBF rule to edit. Can be retrieved from the pan-os-list-pbf-rules command. name: rulename @@ -9271,7 +9268,6 @@ script: name: device-group description: Deletes an application-group. name: pan-os-delete-application-group - outputs: [] - arguments: - description: Whether to include shared tags in the list. name: include_shared_tags diff --git a/Packs/PAN-OS/Integrations/Panorama/Panorama_description.md b/Packs/PAN-OS/Integrations/Panorama/Panorama_description.md index 6a233d12500f..a17bb1233474 100644 --- a/Packs/PAN-OS/Integrations/Panorama/Panorama_description.md +++ b/Packs/PAN-OS/Integrations/Panorama/Panorama_description.md @@ -1,16 +1,16 @@ The integration uses the Panorama XML API. To obtain an API Key, run the following REST command and copy the key: https://[PanoramaIP]/api/?type=keygen&user=[user]&password=[password] - + For more information, visit the [Palo Alto Networks documentation](https://docs.paloaltonetworks.com/panorama). - + --- You need to create a separate integration instance for Palo Alto Networks Firewall and Palo Alto Networks. Unless specified otherwise, all commands are valid for both Firewall and Panorama. --- ### Firewall: Configure the vsys - The vsys is located in the Firewall URL; e.g., https://#device::::device/setup - + ### Panorama: Configure a device group - Access the Panorama UI. - Go to **Panorama** > **Device Groups**. @@ -18,39 +18,37 @@ You need to create a separate integration instance for Palo Alto Networks Firewa --- ### Fetch Incidents -The Panorama integration now supports fetch incidents. + The Panorama integration now supports fetch incidents. The incidents are fetched according to a number of different optional log type queries. The log types are: **Traffic, Threat, URL, Data, Correlation, System, Wildfire, Decryption**. -##### Max incidents per fetch + ##### Max incidents per fetch The max incidents per fetch parameter specifies the maximum number of incidents to fetch **per** Log Type Query. ##### Log Type -The queries that will be included during the fetch are decided according to the "Log Type" parameter (Multiple select dropdown). + The queries that will be included during the fetch are decided according to the "Log Type" parameter (Multiple select dropdown). - Selecting "All" will use all the log type queries in the fetch. - To choose a specific set of queries, select their log types from the dropdown (make sure "All" option is unselected). -##### Log Type Query + ##### Log Type Query - Each log type has its own query field in the instance configuration. - Note that the default query values has some example text in it, make sure to enter a valid query. ##### Log Type Query Examples | Log Type | Query Example | -|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| -| Traffic | (addr.src in {source}) and (addr.dst in {destination}) and (action eq {action}) | + |---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| + | Traffic | (addr.src in {source}) and (addr.dst in {destination}) and (action eq {action}) | | Threat | (severity geq high) | | URL | ((action eq block-override) or (action eq block-url)) and (severity geq high) | | Data | ((action eq alert) or (action eq wildfire-upload-success) or (action eq forward)) and (severity geq high) | | Correlation | (hostid eq {host_id}) and (match_time in {last_x_time}) and (objectname eq {object_name}) and (severity geq '{severity}') and (src in {source_address}) | -| System | (subtype eq {sub_type}) and (severity geq {severity}) | + | System | (subtype eq {sub_type}) and (severity geq {severity}) | | Wildfire Submission | ((action eq wildfire-upload-fail) or (action eq wildfire-upload-skip) or (action eq sinkhole)) | | Decryption | (app eq {application}) and (policy_name geq {policy_name}) and ((src in {source}) or (dst in {destination})) | ##### Classifiers and Mappers - + This integration supports a default Classifier (Panorama Classifier) and Mapper (Panorama Mapper) that handles incidents returned from the API. ---- - -[View Integration Documentation](https://xsoar.pan.dev/docs/reference/integrations/panorama) +--- \ No newline at end of file diff --git a/Packs/PAN-OS/Integrations/Panorama/Panorama_test.py b/Packs/PAN-OS/Integrations/Panorama/Panorama_test.py index 5fa916c5084d..c4da35b417e9 100644 --- a/Packs/PAN-OS/Integrations/Panorama/Panorama_test.py +++ b/Packs/PAN-OS/Integrations/Panorama/Panorama_test.py @@ -4029,7 +4029,7 @@ def test_pan_os_get_running_config(mocker): SOME_SERIAL_NUMBER not connected """ mocker.patch("Panorama.http_request", return_value=return_mock) - created_file = pan_os_get_running_config({"target": "SOME_SERIAL_NUMBER"}) + created_file = pan_os_get_running_config({"target": "SOME_SERIAL_NUMBER", "filename": "running_config"}) assert created_file['File'] == 'running_config' diff --git a/Packs/PAN-OS/ReleaseNotes/2_1_22.md b/Packs/PAN-OS/ReleaseNotes/2_1_22.md new file mode 100644 index 000000000000..33792fcbdab3 --- /dev/null +++ b/Packs/PAN-OS/ReleaseNotes/2_1_22.md @@ -0,0 +1,7 @@ +#### Integrations + +##### Palo Alto Networks PAN-OS + +- Added the feature to append a filename string to the run-config and device state files for the following commands: + ***pan-os-platform-get-device-state*** + ***pan-os-get-running-config*** diff --git a/Packs/PAN-OS/pack_metadata.json b/Packs/PAN-OS/pack_metadata.json index 5382494f2859..30c11b50680a 100644 --- a/Packs/PAN-OS/pack_metadata.json +++ b/Packs/PAN-OS/pack_metadata.json @@ -2,7 +2,7 @@ "name": "PAN-OS by Palo Alto Networks", "description": "Manage Palo Alto Networks Firewall and Panorama. Use this pack to manage Prisma Access through Panorama. For more information see Panorama documentation.", "support": "xsoar", - "currentVersion": "2.1.21", + "currentVersion": "2.1.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 0136b7e67ad7e7afe35b291253d38727e3954dac Mon Sep 17 00:00:00 2001 From: Adi Daud <46249224+adi88d@users.noreply.github.com> Date: Sun, 25 Feb 2024 16:53:33 +0200 Subject: [PATCH 080/272] Fix retrieve the SDK changelog workflow status while loop (#33093) * sleep before retrieve the SDK changelog workflow status * Update create_sdk_pr.py * Update create_sdk_pr.py * Update create_sdk_pr.py --- Tests/sdk_release/create_sdk_pr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/sdk_release/create_sdk_pr.py b/Tests/sdk_release/create_sdk_pr.py index 8d9597469f12..e5f9453709f8 100644 --- a/Tests/sdk_release/create_sdk_pr.py +++ b/Tests/sdk_release/create_sdk_pr.py @@ -180,6 +180,7 @@ def main(): elapsed: float = 0 start = time.time() while elapsed < TIMEOUT: + time.sleep(10) response = requests.request('GET', url, headers=headers, verify=False) if response.status_code != requests.codes.ok: logging.error('Failed to retrieve SDK changelog workflow status') @@ -193,7 +194,6 @@ def main(): break logging.info(f'waiting to SDK changelog workflow to finish, current status: {status}') - time.sleep(10) elapsed = time.time() - start if elapsed >= TIMEOUT: From f1b45801340a92f11f67050e2f0aef563e0778f7 Mon Sep 17 00:00:00 2001 From: dorschw <81086590+dorschw@users.noreply.github.com> Date: Sun, 25 Feb 2024 16:59:49 +0200 Subject: [PATCH 081/272] fix infra mypy errors (#33067) --- Tests/scripts/common.py | 2 +- Tests/scripts/gitlab_slack_notifier.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/scripts/common.py b/Tests/scripts/common.py index dc6aabdf9d8b..3ba7843f06f7 100644 --- a/Tests/scripts/common.py +++ b/Tests/scripts/common.py @@ -169,7 +169,7 @@ def calculate_results_table(jira_tickets_for_result: dict[str, Issue], skipped_count = 0 errors_count = 0 for server_version in server_versions_list: - test_suite: TestSuite = result_test_suites.get(server_version) + test_suite: TestSuite | None = result_test_suites.get(server_version) if test_suite: xml.add_testsuite(test_suite) row.append( diff --git a/Tests/scripts/gitlab_slack_notifier.py b/Tests/scripts/gitlab_slack_notifier.py index eca50e9e9136..4283abdf7411 100644 --- a/Tests/scripts/gitlab_slack_notifier.py +++ b/Tests/scripts/gitlab_slack_notifier.py @@ -237,7 +237,7 @@ def get_playbook_tests_data(artifact_folder: Path) -> tuple[set[str], set[str], failed_tests = set() skipped_tests = set() skipped_integrations = set(split_results_file(get_artifact_data(artifact_folder, 'skipped_integrations.txt'))) - xml = JUnitXml.fromfile(artifact_folder / TEST_PLAYBOOKS_REPORT_FILE_NAME) + xml = JUnitXml.fromfile(str(artifact_folder / TEST_PLAYBOOKS_REPORT_FILE_NAME)) for test_suite in xml.iterchildren(TestSuite): properties = get_properties_for_test_suite(test_suite) if playbook_id := properties.get("playbook_id"): From 8bc42be25036ec72b39311f934f5de43b47d3d88 Mon Sep 17 00:00:00 2001 From: dorschw <81086590+dorschw@users.noreply.github.com> Date: Sun, 25 Feb 2024 17:26:37 +0200 Subject: [PATCH 082/272] pre-commit: Upload pytest junit artifact (#33033) --- .github/workflows/pre-commit-reuse.yml | 38 ++++++++++- .../parse_junit_per_pack.py | 65 +++++++++++++++++++ Utils/tests/test_parse_junit_per_pack.py | 64 ++++++++++++++++++ 3 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 Utils/github_workflow_scripts/parse_junit_per_pack.py create mode 100644 Utils/tests/test_parse_junit_per_pack.py diff --git a/.github/workflows/pre-commit-reuse.yml b/.github/workflows/pre-commit-reuse.yml index 954133224066..c8375e31a4b6 100644 --- a/.github/workflows/pre-commit-reuse.yml +++ b/.github/workflows/pre-commit-reuse.yml @@ -19,6 +19,9 @@ jobs: with: fetch-depth: 0 + - name: Set PYTHONPATH + run: echo "PYTHONPATH=$GITHUB_WORKSPACE" >> $GITHUB_ENV + - name: Setup python uses: actions/setup-python@v4 with: @@ -45,13 +48,44 @@ jobs: - name: "Check coverage.xml exists" if: always() - id: check_files + id: check-coverage-xml-exists uses: andstor/file-existence-action@v2 with: files: "coverage_report/coverage.xml" + - name: "Check pytest report exists" + if: always() + id: check-pytest-junit-exists + uses: andstor/file-existence-action@v2 + with: + files: ".report_pytest.xml" + + - name: Create pack-wise pytest report + run: poetry run python Utils/github_workflow_scripts/parse_junit_per_pack.py + if: | + always() && + steps.check-pytest-junit-exists.outputs.files_exists == 'true' && + github.event.pull_request.head.repo.fork == false + + - name: Upload junit & pack-wise pytest report + uses: actions/upload-artifact@v4 + if: | + always() && + steps.check-pytest-junit-exists.outputs.files_exists == 'true' && + github.event.pull_request.head.repo.fork == false + with: + name: pytest + path: | + packwise_pytest_time.csv + .report_pytest.xml + if-no-files-found: error + - name: Pytest coverage comment - if: always() && steps.check_files.outputs.files_exists == 'true' && github.event.pull_request.head.repo.fork == false + if: | + always() && + steps.check-coverage-xml-exists.outputs.files_exists == 'true' && + steps.check-pytest-junit-exists.outputs.files_exists == false && + github.event.pull_request.head.repo.fork == false uses: MishaKav/pytest-coverage-comment@main with: pytest-xml-coverage-path: coverage_report/coverage.xml diff --git a/Utils/github_workflow_scripts/parse_junit_per_pack.py b/Utils/github_workflow_scripts/parse_junit_per_pack.py new file mode 100644 index 000000000000..c620bac9a81e --- /dev/null +++ b/Utils/github_workflow_scripts/parse_junit_per_pack.py @@ -0,0 +1,65 @@ +from collections import defaultdict +import operator +import xml.etree.ElementTree as ET +from pathlib import Path +import csv + + +class PackNameParseError(Exception): + def __init__(self, value: str) -> None: + self.value = value + super().__init__( + f"Cannot parse pack name out of {value}, expected Packs..more_parts" + ) + + +def parse_pack_name(class_name: str): + # parses Packs.IPINFO.Integrations.ipinfo_v2.ipinfo_v2_test into IPINFO + if ( + (not class_name.startswith("Packs.")) + or len(parts := class_name.split(".")) < 3 + or not (parsed_pack_name := parts[1]) + ): + raise PackNameParseError(class_name) + return parsed_pack_name + + +def parse_xml(path: Path = Path(".report_pytest.xml")) -> dict[str, float]: + pack_times: defaultdict[str, float] = defaultdict(int) + + for suite in ET.parse(path).getroot().findall("testsuite"): + for case in suite.findall("testcase"): + pack_name = parse_pack_name(case.attrib["classname"]) + pack_times[pack_name] += float(case.attrib["time"]) + return dict( + sorted( + pack_times.items(), + key=operator.itemgetter(1), + reverse=True, # Sorted by descending duration + ) + ) + + +def write_csv(pack_times: dict[str, float], output_path: Path) -> None: + with output_path.open("w", newline="") as file: + writer = csv.DictWriter( + file, + ["pack", "duration"], + ) + writer.writeheader() + writer.writerows( + [ + { + "pack": pack, + "duration": str( + round(duration, 2) + ), # str avoids floating point percision + } + for pack, duration in pack_times.items() + ] + ) + + +if __name__ == "__main__": + pack_times = parse_xml() + write_csv(pack_times, Path("packwise_pytest_time.csv")) diff --git a/Utils/tests/test_parse_junit_per_pack.py b/Utils/tests/test_parse_junit_per_pack.py new file mode 100644 index 000000000000..45b46afcdbe1 --- /dev/null +++ b/Utils/tests/test_parse_junit_per_pack.py @@ -0,0 +1,64 @@ +from Utils.github_workflow_scripts.parse_junit_per_pack import ( + parse_pack_name, + parse_xml, + PackNameParseError, +) +from pathlib import Path +import pytest + + +def test_parse_xml(tmp_path): + """ + Given a junit.xml file + When calling parse_xml + Then make sure the output is correct + """ + (xml_path := Path(tmp_path, "foo.xml")).write_text( + "" + '' # noqa: E501 + '' + '' # noqa: E501 + '' # noqa: E501 + '' # noqa: E501 + '' + '' # noqa: E501 + '' + "" + ) + result = parse_xml(xml_path) + assert tuple(result.keys())[0] == "qradar" # test sort + assert parse_xml(xml_path) == {"ipinfo": 0.035, "qradar": 0.21} + + +@pytest.mark.parametrize( + "value,pack_name", + ( + ("Packs.pack1.foo", "pack1"), + ("Packs.pack1.foo.bar", "pack1"), + ("Packs.pack2.foo.bar.baz", "pack2"), + ), +) +def test_parse_pack_name(value: str, pack_name: str): + """ + Given a string representing a valid junit class_name of a content pack + When calling parse_pack_name + Then make sure the output is correct + """ + assert parse_pack_name(value) == pack_name + + +@pytest.mark.parametrize( + "value", + ("", " ", "foo", "Packs.", "Tests.pack1", "Utils.pack1", "Packs.Pack", "Packs.."), +) +def test_parse_pack_name_error(value: str): + """ + Given a string representing an INvalid junit class_name of a content pack + When calling parse_pack_name + Then make sure an appropriate exception is raised + """ + with pytest.raises( + PackNameParseError, + match=f"Cannot parse pack name out of {value}, expected Packs..more_parts", + ): + parse_pack_name(value) From 7a5cb500088ca0511cc71192ce5eec1029a5e850 Mon Sep 17 00:00:00 2001 From: Jasmine Beilin <71636766+JasBeilin@users.noreply.github.com> Date: Sun, 25 Feb 2024 17:46:37 +0200 Subject: [PATCH 083/272] JoeSecurityv2 fixed filename and comment (#32819) * fixed filename and comment * Update Packs/JoeSecurity/Integrations/JoeSecurityV2/JoeSecurityV2.py * test * issue fix * Update README.md * Update README.md * fix comment argument * RN * fix * Update JoeSecurityV2.py * fix pre commit --- .../Integrations/JoeSecurityV2/JoeSecurityV2.py | 9 ++++++--- Packs/JoeSecurity/ReleaseNotes/1_1_19.md | 6 ++++++ Packs/JoeSecurity/pack_metadata.json | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 Packs/JoeSecurity/ReleaseNotes/1_1_19.md diff --git a/Packs/JoeSecurity/Integrations/JoeSecurityV2/JoeSecurityV2.py b/Packs/JoeSecurity/Integrations/JoeSecurityV2/JoeSecurityV2.py index 00b8e4bf1c37..847a35e98f43 100644 --- a/Packs/JoeSecurity/Integrations/JoeSecurityV2/JoeSecurityV2.py +++ b/Packs/JoeSecurity/Integrations/JoeSecurityV2/JoeSecurityV2.py @@ -457,7 +457,7 @@ def build_submission_params(args: Dict[str, Any], on_premise: bool) -> Dict[str, Returns: result: (Dict[str, Any]): The submission parameters. """ - params = {'comments': args.get('comment', None), 'systems': argToList(args.get('systems')), + params = {'comments': args.get('comments', None), 'systems': argToList(args.get('systems')), 'tags': argToList(args.get('tags')), 'internet-access': argToBoolean(args.get('internet_access', True)), 'archive-no-unpack': argToBoolean(args.get('archive_no_unpack', False)), 'ssl-inspection': argToBoolean(args.get('ssl_inspection', False)), @@ -504,9 +504,12 @@ def file_submission(client: Client, args: Dict[str, Any], params: Dict[str, Any] result: (PollResult): The parsed PollResult object. """ file_path = demisto.getFilePath(file) + name = file_path['name'] + demisto.debug(f"Trying to upload file {name=} from entry= {file_path['path']}") + with open(file_path['path'], 'rb') as f: - s = (args.get('file_name'), f) if args.get('file_name') else f - res = client.submit_sample(sample=s, params=params, cookbook=args.get('cookbook')) + file_to_send = (args.get('file_name') or name, f) + res = client.submit_sample(sample=file_to_send, params=params, cookbook=args.get('cookbook')) exe_metrics.success += 1 partial_res = CommandResults( readable_output=f'Waiting for submission "{res.get("submission_id")}" to finish...') diff --git a/Packs/JoeSecurity/ReleaseNotes/1_1_19.md b/Packs/JoeSecurity/ReleaseNotes/1_1_19.md new file mode 100644 index 000000000000..cf2359b8c795 --- /dev/null +++ b/Packs/JoeSecurity/ReleaseNotes/1_1_19.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Joe Security v2 + +- Fixed an issue where *comments* argument was not passed correctly in the ***joe-submit-sample*** command. diff --git a/Packs/JoeSecurity/pack_metadata.json b/Packs/JoeSecurity/pack_metadata.json index 86b353bcbe25..db23e7186b37 100644 --- a/Packs/JoeSecurity/pack_metadata.json +++ b/Packs/JoeSecurity/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Joe Security", "description": "Sandbox Cloud", "support": "xsoar", - "currentVersion": "1.1.18", + "currentVersion": "1.1.19", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e89904807690f41a0fa066a15f535577d539a35e Mon Sep 17 00:00:00 2001 From: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Date: Sun, 25 Feb 2024 18:28:21 +0200 Subject: [PATCH 084/272] [Microsoft Graph Security] msg-purge-ediscovery-data - update docs (#33054) * test * update * remove from skipped_tests * Update Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_9.md Co-authored-by: Yuval Cohen <86777474+yucohen@users.noreply.github.com> --------- Co-authored-by: Yuval Cohen <86777474+yucohen@users.noreply.github.com> --- .../MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml | 4 +++- Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_9.md | 6 ++++++ .../Microsoft_Graph_security_test_ediscovery.yml | 2 +- Packs/MicrosoftGraphSecurity/pack_metadata.json | 2 +- Tests/conf.json | 3 +-- 5 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_9.md diff --git a/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml b/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml index 26b8e904938d..9caab1d1c755 100644 --- a/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml +++ b/Packs/MicrosoftGraphSecurity/Integrations/MicrosoftGraphSecurity/MicrosoftGraphSecurity.yml @@ -1601,7 +1601,8 @@ script: required: false auto: PREDEFINED predefined: - - permanentlyDelete + - permanentlydeleted + - recoverable - description: The ID of the eDiscovery search. isArray: false name: purge_areas @@ -1609,6 +1610,7 @@ script: auto: PREDEFINED predefined: - teamsMessages + - mailboxes description: |- Delete Microsoft Teams messages contained in an eDiscovery search. Note: This request purges Teams data only. It does not purge other types of data such as mailbox items. diff --git a/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_9.md b/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_9.md new file mode 100644 index 000000000000..78ed79050db1 --- /dev/null +++ b/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_9.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Graph Security + +Updated the **purge_areas** and **purge_type** arguments of the ***msg-purge-ediscovery-data*** command to include only the purgeType and purgeAreas options supported by Microsoft. \ No newline at end of file diff --git a/Packs/MicrosoftGraphSecurity/TestPlaybooks/Microsoft_Graph_security_test_ediscovery.yml b/Packs/MicrosoftGraphSecurity/TestPlaybooks/Microsoft_Graph_security_test_ediscovery.yml index 3701576601ae..e3092147f381 100644 --- a/Packs/MicrosoftGraphSecurity/TestPlaybooks/Microsoft_Graph_security_test_ediscovery.yml +++ b/Packs/MicrosoftGraphSecurity/TestPlaybooks/Microsoft_Graph_security_test_ediscovery.yml @@ -1598,7 +1598,7 @@ tasks: purge_areas: simple: teamsMessages purge_type: - simple: permanentlyDelete + simple: permanentlydeleted search_id: simple: ${SearchID} separatecontext: false diff --git a/Packs/MicrosoftGraphSecurity/pack_metadata.json b/Packs/MicrosoftGraphSecurity/pack_metadata.json index 0cefa88a578c..4d5be5550c33 100644 --- a/Packs/MicrosoftGraphSecurity/pack_metadata.json +++ b/Packs/MicrosoftGraphSecurity/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Security", "description": "Unified gateway to security insights - all from a unified Microsoft Graph\n Security API.", "support": "xsoar", - "currentVersion": "2.2.8", + "currentVersion": "2.2.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Tests/conf.json b/Tests/conf.json index 0cfb66b0a6c3..fdc83215ea3d 100644 --- a/Tests/conf.json +++ b/Tests/conf.json @@ -5865,8 +5865,7 @@ "ThreatStream-Test": "Issue CRTX-96526", "MSG-Threat-Assessment-test": "API limitation", "BambenekConsultingFeed_Test": "Issue CRTX-99480", - "AWS SNS Listener - Test": "Cant validate mock msg against AWS-SNS in TBP", - "MSG-ediscovery-tpb": "Issue CIAC-9763" + "AWS SNS Listener - Test": "Cant validate mock msg against AWS-SNS in TBP" }, "skipped_integrations": { "EWS Mail Sender": "The integration is deprecated", From 1822ccc41f90130d5a9c148777e2e9682bc027db Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 25 Feb 2024 20:23:32 +0200 Subject: [PATCH 085/272] demisto-sdk-release 1.27.0 (#33095) * poetry files * added demisto-sdk==1.27.0to pre-commit config --------- Co-authored-by: Content Bot Co-authored-by: Shmuel Kroizer --- .pre-commit-config_template.yaml | 2 +- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config_template.yaml b/.pre-commit-config_template.yaml index d58b53d9551c..b872798e1c5e 100644 --- a/.pre-commit-config_template.yaml +++ b/.pre-commit-config_template.yaml @@ -289,7 +289,7 @@ repos: - decorator==5.1.1 ; python_version >= "3.8" and python_version < "3.11" - defusedxml==0.7.1 ; python_version >= "3.8" and python_version < "3.11" - demisto-py==3.2.13 ; python_version >= "3.8" and python_version < "3.11" - - demisto-sdk==1.26.2 ; python_version >= "3.8" and python_version < "3.11" + - demisto-sdk==1.27.0 ; python_version >= "3.8" and python_version < "3.11" - dictdiffer==0.9.0 ; python_version >= "3.8" and python_version < "3.11" - dictor==0.1.12 ; python_version >= "3.8" and python_version < "3.11" - distlib==0.3.7 ; python_version >= "3.8" and python_version < "3.11" diff --git a/poetry.lock b/poetry.lock index d398fbfda82e..be71bdf4a200 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand. [[package]] name = "aiodns" @@ -1354,13 +1354,13 @@ urllib3 = ">=1.26.7" [[package]] name = "demisto-sdk" -version = "1.26.2" +version = "1.27.0" description = "\"A Python library for the Demisto SDK\"" optional = false python-versions = ">=3.8,<3.11" files = [ - {file = "demisto_sdk-1.26.2-py3-none-any.whl", hash = "sha256:7ab48aedc3fc5fc4ca6218112e74fd32b0a1e0bfe2183663292a2869fae50789"}, - {file = "demisto_sdk-1.26.2.tar.gz", hash = "sha256:82cfdd01d3755092a8b6f9e96f8bc944241389af4edddffaa9689a1e423ad58d"}, + {file = "demisto_sdk-1.27.0-py3-none-any.whl", hash = "sha256:73d318b8fd837f5b380244178945d320c40e6655b86ca11eecb1ccf63f5794cb"}, + {file = "demisto_sdk-1.27.0.tar.gz", hash = "sha256:1ccc523a79429df1d21a5f363b2775220b84e9cc48652bda52f8ff204ce7bf92"}, ] [package.dependencies] @@ -7145,4 +7145,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = "^3.8,<3.11" -content-hash = "d3f7e559f476574e4f2d3b6b4612422e70ed0f81a52b76ac6db2ab021220a42c" +content-hash = "470d1a10cc2545cb9dd376fa129f0410aec8bd61c3c6e9a8dbaf38eafa07f6be" diff --git a/pyproject.toml b/pyproject.toml index eb159fa7a321..ccc3927509ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ python = "^3.8,<3.11" defusedxml = "^0.7.1" [tool.poetry.group.dev.dependencies] -demisto-sdk = "1.26.2" +demisto-sdk = "1.27.0" requests = "^2.22.0" pre-commit = "^3.5.0" google-cloud-compute = "^1.8.0" From 8fcd682758956313b3fb5a570ca50719451f8053 Mon Sep 17 00:00:00 2001 From: omerKarkKatz <95565843+omerKarkKatz@users.noreply.github.com> Date: Sun, 25 Feb 2024 20:31:06 +0200 Subject: [PATCH 086/272] Add a limit to cs falcon search device command (#32979) * added a limit parameter to search device command * updated release notes * updated docker image * updated the release notes * add BC release ntoes and parameters to endpoint command * docker update * removed the params from the endpoint command * updated the docker image * removed unrelated files * removed unrelated files * Trigger-build --- .../CrowdStrikeFalcon/CrowdStrikeFalcon.py | 4 +++- .../CrowdStrikeFalcon/CrowdStrikeFalcon.yml | 18 ++++++++++++------ .../CrowdStrikeFalcon_test.py | 7 ++++--- .../Integrations/CrowdStrikeFalcon/README.md | 2 ++ .../CrowdStrikeFalcon/ReleaseNotes/1_13_0.json | 4 ++++ Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_0.md | 6 ++++++ Packs/CrowdStrikeFalcon/pack_metadata.json | 2 +- 7 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_0.json create mode 100644 Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_0.md diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py index ed70f3d33a39..17e12cad5c83 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py @@ -1763,6 +1763,8 @@ def search_device(filter_operator='AND'): 'site_name': str(args.get('site_name', '')).split(','), 'local_ip': str(args.get('ip', '')).split(',') } + limit = int(args.get('limit', 50)) + offset = int(args.get('offset', 0)) url_filter = '{}'.format(str(args.get('filter', ''))) op = ',' if filter_operator == 'OR' else '+' # In Falcon Query Language, '+' stands for AND and ',' for OR @@ -1783,7 +1785,7 @@ def search_device(filter_operator='AND'): # All args should be a list. this is a fallback url_filter = "{url_filter}{operator}{inp_arg}:'{arg_val}'".format(url_filter=url_filter, operator=op, inp_arg=k, arg_val=arg) - raw_res = http_request('GET', '/devices/queries/devices/v1', params={'filter': url_filter}) + raw_res = http_request('GET', '/devices/queries/devices/v1', params={'filter': url_filter, 'limit': limit, 'offset': offset}) device_ids = raw_res.get('resources') if not device_ids: return None diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml index f9d0ebcc0b6b..05ca04031968 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml @@ -186,24 +186,30 @@ script: auto: PREDEFINED - description: The query to filter the device. name: filter - - description: A comma-separated list of device IDs to limit the results. + - description: The maximum records to return [1-5000]. + name: limit + defaultValue: 50 + - description: The offset to start retrieving records from. + name: offset + defaultValue: 0 + - description: 'A comma-separated list of device IDs to limit the results.' name: ids - auto: PREDEFINED description: 'The status of the device. Possible values are: "Normal", "containment_pending", "contained", and "lift_containment_pending".' name: status predefined: - - normal + - 'normal' - containment_pending - contained - lift_containment_pending - auto: PREDEFINED - description: The host name of the device. + description: 'The host name of the device.' name: hostname predefined: - '' - - auto: PREDEFINED - description: 'The platform name of the device. Possible values are: Windows, Mac, and Linux.' + - description: 'The platform name of the device. Possible values are: Windows, Mac, and Linux.' name: platform_name + auto: PREDEFINED predefined: - Windows - Mac @@ -4962,7 +4968,7 @@ script: - contextPath: CrowdStrike.IOARules.version_ids description: The IOA Rule's version ID. type: String - dockerimage: demisto/py3-tools:1.0.0.86612 + dockerimage: demisto/py3-tools:1.0.0.88283 isfetch: true ismappable: true isremotesyncin: true diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon_test.py b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon_test.py index a7cde8a8792c..7175122bd68c 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon_test.py +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon_test.py @@ -3517,7 +3517,7 @@ def test_get_endpoint_command(requests_mock, mocker): - The user is running cs-falcon-search-device with an id Then - Return an Endpoint context output - """ + """ from CrowdStrikeFalcon import get_endpoint_command response = {'resources': {'meta': {'query_time': 0.010188508, 'pagination': {'offset': 1, 'limit': 100, 'total': 1}, 'powered_by': 'device-api', 'trace_id': 'c876614b-da71-4942-88db-37b939a78eb3'}, @@ -3560,13 +3560,14 @@ def test_get_endpoint_command(requests_mock, mocker): status_code=200, ) - mocker.patch.object(demisto, 'args', return_value={'id': 'dentifier_numbe', 'hostname': 'falcon-crowdstr'}) + mocker.patch.object(demisto, 'args', return_value={'id': 'identifier_numbe', 'hostname': 'falcon-crowdstr'}) outputs = get_endpoint_command() result = outputs[0].to_context() context = result.get('EntryContext') - assert unquote(query_mocker.last_request.query) == "filter=device_id:'dentifier_numbe',hostname:'falcon-crowdstr'" + api_query = "filter=device_id:'identifier_numbe',hostname:'falcon-crowdstr'&limit=50&offset=0" + assert unquote(query_mocker.last_request.query) == api_query assert context['Endpoint(val.ID && val.ID == obj.ID && val.Vendor == obj.Vendor)'] == [endpoint_context] diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md index 29454898c5ec..6fc72abeded4 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md @@ -156,6 +156,8 @@ Searches for a device that matches the query. | hostname | The host name of the device. Possible values are: . | Optional | | platform_name | The platform name of the device. Possible values are: Windows, Mac, and Linux. Possible values are: Windows, Mac, Linux. | Optional | | site_name | The site name of the device. | Optional | +| limit | The maximum number of records to return. Default is 50. | Optional | +| offset | The offset to begin the list from. For example, start from the 10th record and return the list. Default is 0. | Optional | #### Context Output diff --git a/Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_0.json b/Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_0.json new file mode 100644 index 000000000000..a974f9ef421b --- /dev/null +++ b/Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_0.json @@ -0,0 +1,4 @@ +{ + "breakingChanges": true, + "breakingChangesNotes": "Parameters *limit* (with defualt value 50) and *offset* (with defualt value 0), were introduced to ***cs-falcon-search-device*** command. Number of returned results will be defined by the limit" +} \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_0.md b/Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_0.md new file mode 100644 index 000000000000..0fc0462082a1 --- /dev/null +++ b/Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_0.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### CrowdStrike Falcon +- Added the *limit* and *offset* parameter to the ***cs-falcon-search-device*** command. +- Updated the Docker image to: *demisto/py3-tools:1.0.0.88283*. diff --git a/Packs/CrowdStrikeFalcon/pack_metadata.json b/Packs/CrowdStrikeFalcon/pack_metadata.json index 0bebbf755bfd..4fb1b22f31bd 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.12.17", + "currentVersion": "1.13.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e6f052d05b115b557eef423e197e21e94b8465b4 Mon Sep 17 00:00:00 2001 From: Adi Bamberger Edri <72088126+BEAdi@users.noreply.github.com> Date: Sun, 25 Feb 2024 21:00:42 +0200 Subject: [PATCH 087/272] Fixed error runner not found (#33031) * add variables * add to all steps --- .gitlab/ci/.gitlab-ci.global.yml | 2 -- .gitlab/ci/.gitlab-ci.on-push.yml | 5 ----- .gitlab/ci/.gitlab-ci.sdk-nightly.yml | 5 ----- .gitlab/ci/.gitlab-ci.variables.yml | 2 ++ 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/.gitlab/ci/.gitlab-ci.global.yml b/.gitlab/ci/.gitlab-ci.global.yml index c7df44c12e4a..b9fd6f748bb8 100644 --- a/.gitlab/ci/.gitlab-ci.global.yml +++ b/.gitlab/ci/.gitlab-ci.global.yml @@ -501,8 +501,6 @@ stage: unittests-and-validations extends: - .default-job-settings - variables: - KUBERNETES_CPU_REQUEST: 1000m artifacts: expire_in: 30 days paths: diff --git a/.gitlab/ci/.gitlab-ci.on-push.yml b/.gitlab/ci/.gitlab-ci.on-push.yml index 791fd1599d06..4d462e71cdd0 100644 --- a/.gitlab/ci/.gitlab-ci.on-push.yml +++ b/.gitlab/ci/.gitlab-ci.on-push.yml @@ -132,7 +132,6 @@ validate-content-conf: cache: policy: pull-push variables: - KUBERNETES_CPU_REQUEST: 2000m EXTRACT_PRIVATE_TESTDATA: "true" stage: prepare-testing-bucket script: @@ -375,10 +374,6 @@ tests_xsoar_server: rules: - !reference [.filter-non-nightly-docker-updates-rule, rules] - if: '$CI_PIPELINE_SOURCE =~ /^(push|contrib)$/' - - if: '$NIGHTLY' - when: always - variables: - KUBERNETES_CPU_REQUEST: 2000m parallel: matrix: - INSTANCE_ROLE: diff --git a/.gitlab/ci/.gitlab-ci.sdk-nightly.yml b/.gitlab/ci/.gitlab-ci.sdk-nightly.yml index 263e70e179e1..bc79ef9ddf7a 100644 --- a/.gitlab/ci/.gitlab-ci.sdk-nightly.yml +++ b/.gitlab/ci/.gitlab-ci.sdk-nightly.yml @@ -108,7 +108,6 @@ demisto_sdk_nightly:check_idset_dependent_commands: variables: true variables: IS_NIGHTLY: "false" - KUBERNETES_CPU_REQUEST: 1000m PRODUCT_TYPE: "XSOAR" SERVER_TYPE: "XSOAR" INSTANCE_ROLE: "Server Master" @@ -165,7 +164,6 @@ demisto-sdk-nightly:xsoar-prepare-testing-bucket: ARTIFACTS_FOLDER_INSTANCE: "${ARTIFACTS_FOLDER_XSOAR}/instance_${INSTANCE_ROLE}" ARTIFACTS_FOLDER_SERVER_TYPE: "${ARTIFACTS_FOLDER_XSOAR}/server_type_${SERVER_TYPE}" IFRA_ENV_TYPE: "Server Master" - KUBERNETES_CPU_REQUEST: 2000m MARKETPLACE_VERSION: "xsoar" MARKETPLACE_BUCKET: "$GCS_MARKET_BUCKET" cache: @@ -194,7 +192,6 @@ demisto-sdk-nightly:mpv2-prepare-testing-bucket: MARKETPLACE_BUCKET: "$GCS_MARKET_V2_BUCKET" PRODUCT_NAME: "Cortex XSIAM" IFRA_ENV_TYPE: "Server Master" - KUBERNETES_CPU_REQUEST: 2000m cache: policy: pull-push needs: [] @@ -219,7 +216,6 @@ demisto-sdk-nightly:xpanse-prepare-testing-bucket: PRODUCT_NAME: "Cortex XPANSE" MARKETPLACE_BUCKET: "$GCS_MARKET_XPANSE_BUCKET" IFRA_ENV_TYPE: "Server Master" - KUBERNETES_CPU_REQUEST: 2000m cache: policy: pull-push needs: [] @@ -237,7 +233,6 @@ demisto-sdk-nightly:xsoar-saas-prepare-testing-bucket: - .sdk-nightly-schedule-rule variables: IFRA_ENV_TYPE: "Server Master" - KUBERNETES_CPU_REQUEST: 2000m PRODUCT_TYPE: "XSOAR" SERVER_TYPE: "XSOAR SAAS" ARTIFACTS_FOLDER: "${ARTIFACTS_FOLDER_XSOAR}" diff --git a/.gitlab/ci/.gitlab-ci.variables.yml b/.gitlab/ci/.gitlab-ci.variables.yml index 9f5d98af61b5..639863ec6e36 100644 --- a/.gitlab/ci/.gitlab-ci.variables.yml +++ b/.gitlab/ci/.gitlab-ci.variables.yml @@ -46,3 +46,5 @@ variables: POETRY_VERSION: "1.6.1" INSTALL_POETRY: "true" DOCKER_IO: "docker.io" # defined in the project level CI/CD variables + KUBERNETES_CPU_REQUEST: 2 + KUBERNETES_MEMORY_REQUEST: 2Gi From 94c52872f33dfbe42bf5a4401a188bb4114389ea Mon Sep 17 00:00:00 2001 From: samuelFain <65926551+samuelFain@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:05:17 +0200 Subject: [PATCH 088/272] Upgrade native:candidate to 8.6 (#33094) --- Tests/docker_native_image_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/docker_native_image_config.json b/Tests/docker_native_image_config.json index 550e1ae0f836..5d4ceb27c426 100644 --- a/Tests/docker_native_image_config.json +++ b/Tests/docker_native_image_config.json @@ -94,7 +94,7 @@ "netutils", "auth-utils" ], - "docker_ref": "demisto/py3-native:8.4.0.86696" + "docker_ref": "demisto/py3-native:8.6.0.88298" } }, "ignored_content_items":[ From 2fd0e3ab839d1b7e7e9ccda2104179a2afff0ca4 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:53:10 +0200 Subject: [PATCH 089/272] Add alert output content as specified in yml file (#120) (#33030) (#33092) * Add alert output content as specified in yml file (#120) * Add alert output content as specified in yml file Also update command outputs in the yml file * Add release notes and update the app's version * Update integration readme * Update Packs/ZeroFox/ReleaseNotes/1_2_8.md --------- Co-authored-by: Felipe Garrido Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> --- Packs/ZeroFox/Integrations/ZeroFox/README.md | 317 ++++++-- Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.py | 18 + .../ZeroFox/Integrations/ZeroFox/ZeroFox.yml | 675 ++++++++++++++++-- Packs/ZeroFox/ReleaseNotes/1_2_8.md | 6 + Packs/ZeroFox/pack_metadata.json | 4 +- 5 files changed, 883 insertions(+), 137 deletions(-) create mode 100644 Packs/ZeroFox/ReleaseNotes/1_2_8.md diff --git a/Packs/ZeroFox/Integrations/ZeroFox/README.md b/Packs/ZeroFox/Integrations/ZeroFox/README.md index 5e5587e4226f..534af730650a 100644 --- a/Packs/ZeroFox/Integrations/ZeroFox/README.md +++ b/Packs/ZeroFox/Integrations/ZeroFox/README.md @@ -1,5 +1,5 @@ Cloud-based SaaS to detect risks found on social media and digital channels. -This integration was integrated and tested with version 1.0 and 2.0 of ZeroFox +This integration was integrated and tested with versions 1.0 and 2.0 of ZeroFox. ## Configure ZeroFox on Cortex XSOAR @@ -9,9 +9,10 @@ This integration was integrated and tested with version 1.0 and 2.0 of ZeroFox | **Parameter** | **Required** | | --- | --- | - | URL (e.g., ) | True | + | URL (e.g., https://api.zerofox.com/) | True | | Username | True | | Password | True | + | Fetch only escalated alerts | False | | Trust any certificate (not secure) | False | | Use system proxy settings | False | | First fetch timestamp (<number> <time unit>, e.g., 12 hours, 7 days) | False | @@ -64,16 +65,16 @@ Fetches an alert by ID. | ZeroFox.Alert.Perpetrator.ID | Number | The ZeroFox resource ID of the alert perpetrator. | | ZeroFox.Alert.Perpetrator.Network | String | The network containing the offending content. | | ZeroFox.Alert.RuleGroupID | Number | The ID of the rule group. | -| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested", or "Whitelisted". | -| ZeroFox.Alert.Timestamp | Date | The date-time string when an the alert was created, in ISO-8601 format. | -| ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule was deleted. | +| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". | +| ZeroFox.Alert.Timestamp | Date | The date-time string when an alert was created, in ISO-8601 format. | +| ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | | ZeroFox.Alert.LastModified | Date | The date and time at which an alert was last modified. | | ZeroFox.Alert.DarkwebTerm | String | Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. | | ZeroFox.Alert.Reviewed | Boolean | Whether an alert was reviewed. | | ZeroFox.Alert.Escalated | Boolean | Whether an alert was escalated. | | ZeroFox.Alert.Network | String | The network on which an alert was created. | | ZeroFox.Alert.ProtectedSocialObject | String | The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, \(account information or an incoming or outgoing content\), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. | -| ZeroFox.Alert.Notes | String | Notes made on an alert by the user. | +| ZeroFox.Alert.Notes | String | Notes made on an alert. | | ZeroFox.Alert.RuleID | Number | The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | | ZeroFox.Alert.Tags | String | A list of an alert's tags. | | ZeroFox.Alert.EntityAccount | String | The account associated with the entity. | @@ -98,8 +99,38 @@ Assigns an alert to a user. | **Path** | **Type** | **Description** | | --- | --- | --- | -| ZeroFox.Alert.ID | Number | The ID of an alert. | +| ZeroFox.Alert.AlertType | String | The type of an alert. | +| ZeroFox.Alert.OffendingContentURL | String | The URL to the site containing content that triggered an alert. | | ZeroFox.Alert.Assignee | String | The user to which an alert is assigned. | +| ZeroFox.Alert.Entity.ID | Number | The ID of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Name | String | The name of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Image | String | The URL to the profile image of the entity on which an alert was created. | +| ZeroFox.Alert.EntityTerm.ID | Number | The ID of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Name | String | The name of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Deleted | Boolean | Whether an entity term was deleted. | +| ZeroFox.Alert.ContentCreatedAt | Date | The date-time string indicating when the alerted content was created, in ISO-8601 format. | +| ZeroFox.Alert.ID | Number | The ID of an alert. | +| ZeroFox.Alert.RiskRating | Number | The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". | +| ZeroFox.Alert.Perpetrator.Name | String | For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. | +| ZeroFox.Alert.Perpetrator.URL | String | The URL at which you can view the basic details of the perpetrator. | +| ZeroFox.Alert.Perpetrator.Timestamp | Date | The timestamp of a post created by a perpetrator. | +| ZeroFox.Alert.Perpetrator.Type | String | The type of perpetrator on which an alert was created. Can be an account, page, or post. | +| ZeroFox.Alert.Perpetrator.ID | Number | The ZeroFox resource ID of the alert perpetrator. | +| ZeroFox.Alert.Perpetrator.Network | String | The network containing the offending content. | +| ZeroFox.Alert.RuleGroupID | Number | The ID of the rule group. | +| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". | +| ZeroFox.Alert.Timestamp | Date | The date-time string when an alert was created, in ISO-8601 format. | +| ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.LastModified | Date | The date and time at which an alert was last modified. | +| ZeroFox.Alert.DarkwebTerm | String | Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. | +| ZeroFox.Alert.Reviewed | Boolean | Whether an alert was reviewed. | +| ZeroFox.Alert.Escalated | Boolean | Whether an alert was escalated. | +| ZeroFox.Alert.Network | String | The network on which an alert was created. | +| ZeroFox.Alert.ProtectedSocialObject | String | The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, \(account information or an incoming or outgoing content\), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. | +| ZeroFox.Alert.Notes | String | Notes made on an alert. | +| ZeroFox.Alert.RuleID | Number | The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.Tags | String | A list of an alert's tags. | +| ZeroFox.Alert.EntityAccount | String | The account associated with the entity. | ### zerofox-close-alert @@ -120,8 +151,38 @@ Closes an alert. | **Path** | **Type** | **Description** | | --- | --- | --- | +| ZeroFox.Alert.AlertType | String | The type of an alert. | +| ZeroFox.Alert.OffendingContentURL | String | The URL to the site containing content that triggered an alert. | +| ZeroFox.Alert.Assignee | String | The user to which an alert is assigned. | +| ZeroFox.Alert.Entity.ID | Number | The ID of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Name | String | The name of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Image | String | The URL to the profile image of the entity on which an alert was created. | +| ZeroFox.Alert.EntityTerm.ID | Number | The ID of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Name | String | The name of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Deleted | Boolean | Whether an entity term was deleted. | +| ZeroFox.Alert.ContentCreatedAt | Date | The date-time string indicating when the alerted content was created, in ISO-8601 format. | | ZeroFox.Alert.ID | Number | The ID of an alert. | -| ZeroFox.Alert.Status | String | The status of an alert. | +| ZeroFox.Alert.RiskRating | Number | The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". | +| ZeroFox.Alert.Perpetrator.Name | String | For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. | +| ZeroFox.Alert.Perpetrator.URL | String | The URL at which you can view the basic details of the perpetrator. | +| ZeroFox.Alert.Perpetrator.Timestamp | Date | The timestamp of a post created by a perpetrator. | +| ZeroFox.Alert.Perpetrator.Type | String | The type of perpetrator on which an alert was created. Can be an account, page, or post. | +| ZeroFox.Alert.Perpetrator.ID | Number | The ZeroFox resource ID of the alert perpetrator. | +| ZeroFox.Alert.Perpetrator.Network | String | The network containing the offending content. | +| ZeroFox.Alert.RuleGroupID | Number | The ID of the rule group. | +| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". | +| ZeroFox.Alert.Timestamp | Date | The date-time string when an alert was created, in ISO-8601 format. | +| ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.LastModified | Date | The date and time at which an alert was last modified. | +| ZeroFox.Alert.DarkwebTerm | String | Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. | +| ZeroFox.Alert.Reviewed | Boolean | Whether an alert was reviewed. | +| ZeroFox.Alert.Escalated | Boolean | Whether an alert was escalated. | +| ZeroFox.Alert.Network | String | The network on which an alert was created. | +| ZeroFox.Alert.ProtectedSocialObject | String | The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, \(account information or an incoming or outgoing content\), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. | +| ZeroFox.Alert.Notes | String | Notes made on an alert. | +| ZeroFox.Alert.RuleID | Number | The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.Tags | String | A list of an alert's tags. | +| ZeroFox.Alert.EntityAccount | String | The account associated with the entity. | ### zerofox-alert-request-takedown @@ -140,30 +201,6 @@ Requests a takedown of a specified alert. #### Context Output -| **Path** | **Type** | **Description** | -| --- | --- | --- | -| ZeroFox.Alert.ID | Number | The ID of an alert. | -| ZeroFox.Alert.Status | String | The status of an alert. | - -### zerofox-modify-alert-tags - -*** -Adds tags to and or removes tags from a specified alert. - -#### Base Command - -`zerofox-modify-alert-tags` - -#### Input - -| **Argument Name** | **Description** | **Required** | -| --- | --- | --- | -| action | Adds or removes tags. Possible values are: add, remove. Default is add. | Optional | -| alert_id | The ID of an alert. Can be retrieved by running the zerofox-list-alerts command. | Required | -| tags | A CSV of tags to be added to or removed from an alert. | Required | - -#### Context Output - | **Path** | **Type** | **Description** | | --- | --- | --- | | ZeroFox.Alert.AlertType | String | The type of an alert. | @@ -185,7 +222,7 @@ Adds tags to and or removes tags from a specified alert. | ZeroFox.Alert.Perpetrator.ID | Number | The ZeroFox resource ID of the alert perpetrator. | | ZeroFox.Alert.Perpetrator.Network | String | The network containing the offending content. | | ZeroFox.Alert.RuleGroupID | Number | The ID of the rule group. | -| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested", or "Whitelisted". | +| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". | | ZeroFox.Alert.Timestamp | Date | The date-time string when an alert was created, in ISO-8601 format. | | ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | | ZeroFox.Alert.LastModified | Date | The date and time at which an alert was last modified. | @@ -199,21 +236,22 @@ Adds tags to and or removes tags from a specified alert. | ZeroFox.Alert.Tags | String | A list of an alert's tags. | | ZeroFox.Alert.EntityAccount | String | The account associated with the entity. | -### zerofox-modify-alert-notes +### zerofox-modify-alert-tags *** -Modify the notes from a specified alert. +Adds tags to and or removes tags from a specified alert. #### Base Command -`zerofox-modify-alert-notes` +`zerofox-modify-alert-tags` #### Input | **Argument Name** | **Description** | **Required** | | --- | --- | --- | +| action | Adds or removes tags. Possible values are: add, remove. Default is add. | Optional | | alert_id | The ID of an alert. Can be retrieved by running the zerofox-list-alerts command. | Required | -| notes | The modified notes to update in the alert. | Required | +| tags | A CSV of tags to be added to or removed from an alert. | Required | #### Context Output @@ -238,7 +276,7 @@ Modify the notes from a specified alert. | ZeroFox.Alert.Perpetrator.ID | Number | The ZeroFox resource ID of the alert perpetrator. | | ZeroFox.Alert.Perpetrator.Network | String | The network containing the offending content. | | ZeroFox.Alert.RuleGroupID | Number | The ID of the rule group. | -| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested", or "Whitelisted". | +| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". | | ZeroFox.Alert.Timestamp | Date | The date-time string when an alert was created, in ISO-8601 format. | | ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | | ZeroFox.Alert.LastModified | Date | The date and time at which an alert was last modified. | @@ -379,8 +417,38 @@ Cancels a takedown of a specified alert. | **Path** | **Type** | **Description** | | --- | --- | --- | +| ZeroFox.Alert.AlertType | String | The type of an alert. | +| ZeroFox.Alert.OffendingContentURL | String | The URL to the site containing content that triggered an alert. | +| ZeroFox.Alert.Assignee | String | The user to which an alert is assigned. | +| ZeroFox.Alert.Entity.ID | Number | The ID of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Name | String | The name of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Image | String | The URL to the profile image of the entity on which an alert was created. | +| ZeroFox.Alert.EntityTerm.ID | Number | The ID of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Name | String | The name of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Deleted | Boolean | Whether an entity term was deleted. | +| ZeroFox.Alert.ContentCreatedAt | Date | The date-time string indicating when the alerted content was created, in ISO-8601 format. | | ZeroFox.Alert.ID | Number | The ID of an alert. | -| ZeroFox.Alert.Status | String | The status of an alert. | +| ZeroFox.Alert.RiskRating | Number | The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". | +| ZeroFox.Alert.Perpetrator.Name | String | For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. | +| ZeroFox.Alert.Perpetrator.URL | String | The URL at which you can view the basic details of the perpetrator. | +| ZeroFox.Alert.Perpetrator.Timestamp | Date | The timestamp of a post created by a perpetrator. | +| ZeroFox.Alert.Perpetrator.Type | String | The type of perpetrator on which an alert was created. Can be an account, page, or post. | +| ZeroFox.Alert.Perpetrator.ID | Number | The ZeroFox resource ID of the alert perpetrator. | +| ZeroFox.Alert.Perpetrator.Network | String | The network containing the offending content. | +| ZeroFox.Alert.RuleGroupID | Number | The ID of the rule group. | +| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". | +| ZeroFox.Alert.Timestamp | Date | The date-time string when an alert was created, in ISO-8601 format. | +| ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.LastModified | Date | The date and time at which an alert was last modified. | +| ZeroFox.Alert.DarkwebTerm | String | Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. | +| ZeroFox.Alert.Reviewed | Boolean | Whether an alert was reviewed. | +| ZeroFox.Alert.Escalated | Boolean | Whether an alert was escalated. | +| ZeroFox.Alert.Network | String | The network on which an alert was created. | +| ZeroFox.Alert.ProtectedSocialObject | String | The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, \(account information or an incoming or outgoing content\), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. | +| ZeroFox.Alert.Notes | String | Notes made on an alert. | +| ZeroFox.Alert.RuleID | Number | The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.Tags | String | A list of an alert's tags. | +| ZeroFox.Alert.EntityAccount | String | The account associated with the entity. | ### zerofox-open-alert @@ -401,8 +469,38 @@ Opens an alert. | **Path** | **Type** | **Description** | | --- | --- | --- | +| ZeroFox.Alert.AlertType | String | The type of an alert. | +| ZeroFox.Alert.OffendingContentURL | String | The URL to the site containing content that triggered an alert. | +| ZeroFox.Alert.Assignee | String | The user to which an alert is assigned. | +| ZeroFox.Alert.Entity.ID | Number | The ID of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Name | String | The name of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Image | String | The URL to the profile image of the entity on which an alert was created. | +| ZeroFox.Alert.EntityTerm.ID | Number | The ID of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Name | String | The name of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Deleted | Boolean | Whether an entity term was deleted. | +| ZeroFox.Alert.ContentCreatedAt | Date | The date-time string indicating when the alerted content was created, in ISO-8601 format. | | ZeroFox.Alert.ID | Number | The ID of an alert. | -| ZeroFox.Alert.Status | String | The status of an alert. | +| ZeroFox.Alert.RiskRating | Number | The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". | +| ZeroFox.Alert.Perpetrator.Name | String | For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. | +| ZeroFox.Alert.Perpetrator.URL | String | The URL at which you can view the basic details of the perpetrator. | +| ZeroFox.Alert.Perpetrator.Timestamp | Date | The timestamp of a post created by a perpetrator. | +| ZeroFox.Alert.Perpetrator.Type | String | The type of perpetrator on which an alert was created. Can be an account, page, or post. | +| ZeroFox.Alert.Perpetrator.ID | Number | The ZeroFox resource ID of the alert perpetrator. | +| ZeroFox.Alert.Perpetrator.Network | String | The network containing the offending content. | +| ZeroFox.Alert.RuleGroupID | Number | The ID of the rule group. | +| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". | +| ZeroFox.Alert.Timestamp | Date | The date-time string when an alert was created, in ISO-8601 format. | +| ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.LastModified | Date | The date and time at which an alert was last modified. | +| ZeroFox.Alert.DarkwebTerm | String | Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. | +| ZeroFox.Alert.Reviewed | Boolean | Whether an alert was reviewed. | +| ZeroFox.Alert.Escalated | Boolean | Whether an alert was escalated. | +| ZeroFox.Alert.Network | String | The network on which an alert was created. | +| ZeroFox.Alert.ProtectedSocialObject | String | The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, \(account information or an incoming or outgoing content\), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. | +| ZeroFox.Alert.Notes | String | Notes made on an alert. | +| ZeroFox.Alert.RuleID | Number | The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.Tags | String | A list of an alert's tags. | +| ZeroFox.Alert.EntityAccount | String | The account associated with the entity. | ### zerofox-list-entities @@ -434,14 +532,14 @@ Lists all entities associated with the company of the authorized user. | ZeroFox.Entity.Name | String | The name of the entity. | | ZeroFox.Entity.EmailAddress | String | The email address associated with the entity. | | ZeroFox.Entity.Organization | String | The organization associated with the entity. | -| ZeroFox.Entity.Tags | String | A list of tags of the entity | +| ZeroFox.Entity.Tags | String | A list of tags of the entity. | | ZeroFox.Entity.StrictNameMatching | Boolean | Indicates the type of string matching used for comparing entity names to impersonator names. | | ZeroFox.Entity.PolicyID | Number | The policy ID of the entity. | | ZeroFox.Entity.Profile | String | A link to a profile resource, if applicable. | | ZeroFox.Entity.EntityGroupID | Number | The ID of the entity group. | | ZeroFox.Entity.EntityGroupName | String | The name of the entity group. | | ZeroFox.Entity.TypeID | Number | The ID of the type of entity. | -| ZeroFox.Entity.TypeName | String | The name of the type of entity | +| ZeroFox.Entity.TypeName | String | The name of the type of entity. | ### zerofox-get-entity-types @@ -459,7 +557,6 @@ There are no input arguments for this command. #### Context Output There is no context output for this command. - ### zerofox-get-policy-types *** @@ -476,6 +573,58 @@ There are no input arguments for this command. #### Context Output There is no context output for this command. +### zerofox-modify-alert-notes + +*** +Modify the notes of a specified alert. + +#### Base Command + +`zerofox-modify-alert-notes` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| alert_id | The ID of an alert. Can be retrieved running the zerofox-list-alerts command. | Required | +| notes | The notes to add to an alert. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| ZeroFox.Alert.AlertType | String | The type of an alert. | +| ZeroFox.Alert.OffendingContentURL | String | The URL to the site containing content that triggered an alert. | +| ZeroFox.Alert.Assignee | String | The user to which an alert is assigned. | +| ZeroFox.Alert.Entity.ID | Number | The ID of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Name | String | The name of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Image | String | The URL to the profile image of the entity on which an alert was created. | +| ZeroFox.Alert.EntityTerm.ID | Number | The ID of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Name | String | The name of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Deleted | Boolean | Whether an entity term was deleted. | +| ZeroFox.Alert.ContentCreatedAt | Date | The date-time string indicating when the alerted content was created, in ISO-8601 format. | +| ZeroFox.Alert.ID | Number | The ID of an alert. | +| ZeroFox.Alert.RiskRating | Number | The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". | +| ZeroFox.Alert.Perpetrator.Name | String | For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. | +| ZeroFox.Alert.Perpetrator.URL | String | The URL at which you can view the basic details of the perpetrator. | +| ZeroFox.Alert.Perpetrator.Timestamp | Date | The timestamp of a post created by a perpetrator. | +| ZeroFox.Alert.Perpetrator.Type | String | The type of perpetrator on which an alert was created. Can be an account, page, or post. | +| ZeroFox.Alert.Perpetrator.ID | Number | The ZeroFox resource ID of the alert perpetrator. | +| ZeroFox.Alert.Perpetrator.Network | String | The network containing the offending content. | +| ZeroFox.Alert.RuleGroupID | Number | The ID of the rule group. | +| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". | +| ZeroFox.Alert.Timestamp | Date | The date-time string when an alert was created, in ISO-8601 format. | +| ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.LastModified | Date | The date and time at which an alert was last modified. | +| ZeroFox.Alert.DarkwebTerm | String | Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. | +| ZeroFox.Alert.Reviewed | Boolean | Whether an alert was reviewed. | +| ZeroFox.Alert.Escalated | Boolean | Whether an alert was escalated. | +| ZeroFox.Alert.Network | String | The network on which an alert was created. | +| ZeroFox.Alert.ProtectedSocialObject | String | The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, \(account information or an incoming or outgoing content\), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. | +| ZeroFox.Alert.Notes | String | Notes made on an alert. | +| ZeroFox.Alert.RuleID | Number | The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.Tags | String | A list of an alert's tags. | +| ZeroFox.Alert.EntityAccount | String | The account associated with the entity. | ### zerofox-submit-threat @@ -500,12 +649,43 @@ Submits potential threats into the ZF alert registry for disruption. | **Path** | **Type** | **Description** | | --- | --- | --- | -| ZeroFox.Alert.ID | Number | The ID of the alert created. | +| ZeroFox.Alert.AlertType | String | The type of an alert. | +| ZeroFox.Alert.OffendingContentURL | String | The URL to the site containing content that triggered an alert. | +| ZeroFox.Alert.Assignee | String | The user to which an alert is assigned. | +| ZeroFox.Alert.Entity.ID | Number | The ID of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Name | String | The name of the entity corresponding to the triggered alert. | +| ZeroFox.Alert.Entity.Image | String | The URL to the profile image of the entity on which an alert was created. | +| ZeroFox.Alert.EntityTerm.ID | Number | The ID of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Name | String | The name of the entity term corresponding to the triggered alert. | +| ZeroFox.Alert.EntityTerm.Deleted | Boolean | Whether an entity term was deleted. | +| ZeroFox.Alert.ContentCreatedAt | Date | The date-time string indicating when the alerted content was created, in ISO-8601 format. | +| ZeroFox.Alert.ID | Number | The ID of an alert. | +| ZeroFox.Alert.RiskRating | Number | The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". | +| ZeroFox.Alert.Perpetrator.Name | String | For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. | +| ZeroFox.Alert.Perpetrator.URL | String | The URL at which you can view the basic details of the perpetrator. | +| ZeroFox.Alert.Perpetrator.Timestamp | Date | The timestamp of a post created by a perpetrator. | +| ZeroFox.Alert.Perpetrator.Type | String | The type of perpetrator on which an alert was created. Can be an account, page, or post. | +| ZeroFox.Alert.Perpetrator.ID | Number | The ZeroFox resource ID of the alert perpetrator. | +| ZeroFox.Alert.Perpetrator.Network | String | The network containing the offending content. | +| ZeroFox.Alert.RuleGroupID | Number | The ID of the rule group. | +| ZeroFox.Alert.Status | String | The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". | +| ZeroFox.Alert.Timestamp | Date | The date-time string when an alert was created, in ISO-8601 format. | +| ZeroFox.Alert.RuleName | String | The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.LastModified | Date | The date and time at which an alert was last modified. | +| ZeroFox.Alert.DarkwebTerm | String | Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. | +| ZeroFox.Alert.Reviewed | Boolean | Whether an alert was reviewed. | +| ZeroFox.Alert.Escalated | Boolean | Whether an alert was escalated. | +| ZeroFox.Alert.Network | String | The network on which an alert was created. | +| ZeroFox.Alert.ProtectedSocialObject | String | The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, \(account information or an incoming or outgoing content\), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. | +| ZeroFox.Alert.Notes | String | Notes made on an alert. | +| ZeroFox.Alert.RuleID | Number | The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. | +| ZeroFox.Alert.Tags | String | A list of an alert's tags. | +| ZeroFox.Alert.EntityAccount | String | The account associated with the entity. | ### zerofox-search-compromised-domain *** -Looks for a given domain in Zerofox's CTI feeds +Looks for a given domain in Zerofox's CTI feeds. #### Base Command @@ -521,14 +701,14 @@ Looks for a given domain in Zerofox's CTI feeds | **Path** | **Type** | **Description** | | --- | --- | --- | -| ZeroFox.CompromisedDomains.Domain | string | Domain in which the search domain was found | -| ZeroFox.CompromisedDomains.LastModified | string | Last time that the threat was found | -| ZeroFox.CompromisedDomains.IPs | string | Related domains to the threat separated by commas | +| ZeroFox.CompromisedDomains.Domain | string | Domain in which the search domain was found. | +| ZeroFox.CompromisedDomains.LastModified | string | Last time that the threat was found. | +| ZeroFox.CompromisedDomains.IPs | string | Related domains to the threat separated by commas. | ### zerofox-search-compromised-email *** -Looks for a given email in ZeroFox's CTI feeds +Looks for a given email in ZeroFox's CTI feeds. #### Base Command @@ -544,14 +724,14 @@ Looks for a given email in ZeroFox's CTI feeds | **Path** | **Type** | **Description** | | --- | --- | --- | -| ZeroFox.CompromisedEmails.Domain | string | Domain in which the search domain was found | -| ZeroFox.CompromisedEmails.Email | string | Email involved in the threat | -| ZeroFox.CompromisedEmails.CreatedAt | string | Date in which the email was found related to a threat | +| ZeroFox.CompromisedEmails.Domain | string | Domain in which the search domain was found. | +| ZeroFox.CompromisedEmails.Email | string | Email involved in the threat. | +| ZeroFox.CompromisedEmails.CreatedAt | string | Date in which the email was found related to a threat. | ### zerofox-search-malicious-ip *** -Looks for malicious ips in ZeroFox's CTI feeds +Looks for malicious ips in ZeroFox's CTI feeds. #### Base Command @@ -567,14 +747,14 @@ Looks for malicious ips in ZeroFox's CTI feeds | **Path** | **Type** | **Description** | | --- | --- | --- | -| ZeroFox.MaliciousIPs.Domain | string | Domain in which the search domain was found | -| ZeroFox.MaliciousIPs.IPAddress | string | IP in which the search domain was found | -| ZeroFox.MaliciousIPs.CreatedAt | string | Date in which the ip was found related to a threat | +| ZeroFox.MaliciousIPs.Domain | string | Domain in which the search domain was found. | +| ZeroFox.MaliciousIPs.IPAddress | string | IP in which the search domain was found. | +| ZeroFox.MaliciousIPs.CreatedAt | string | Date in which the ip was found related to a threat. | ### zerofox-search-malicious-hash *** -Looks for registered hashes in ZeroFox's CTI feeds +Looks for registered hashes in ZeroFox's CTI feeds. #### Base Command @@ -590,18 +770,18 @@ Looks for registered hashes in ZeroFox's CTI feeds | **Path** | **Type** | **Description** | | --- | --- | --- | -| ZeroFox.MaliciousHashes.CreatedAt | string | Date in which the ip was found related to a threat | -| ZeroFox.MaliciousHashes.Family | string | Family related threat | -| ZeroFox.MaliciousHashes.MD5 | string | Hash in MD5 format | -| ZeroFox.MaliciousHashes.SHA1 | string | Hash in SHA1 format | -| ZeroFox.MaliciousHashes.SHA256 | string | Hash in SHA256 format | -| ZeroFox.MaliciousHashes.SHA512 | string | Hash in SHA512 format | -| ZeroFox.MaliciousHashes.FoundHash | string | Indicates in which hash format was found the search | +| ZeroFox.MaliciousHashes.CreatedAt | string | Date in which the ip was found related to a threat. | +| ZeroFox.MaliciousHashes.Family | string | Family related threat. | +| ZeroFox.MaliciousHashes.MD5 | string | Hash in MD5 format. | +| ZeroFox.MaliciousHashes.SHA1 | string | Hash in SHA1 format. | +| ZeroFox.MaliciousHashes.SHA256 | string | Hash in SHA256 format. | +| ZeroFox.MaliciousHashes.SHA512 | string | Hash in SHA512 format. | +| ZeroFox.MaliciousHashes.FoundHash | string | Indicates in which hash format was found the search. | ### zerofox-search-exploits *** -Looks for registered exploits in ZeroFox's CTI feeds +Looks for registered exploits in ZeroFox's CTI feeds. #### Base Command @@ -617,15 +797,14 @@ Looks for registered exploits in ZeroFox's CTI feeds | **Path** | **Type** | **Description** | | --- | --- | --- | -| ZeroFox.Exploits.CreatedAt | string | Date in which the ip was found related to a threat | -| ZeroFox.Exploits.CVECode | string | CVE Code to identify the exploit | -| ZeroFox.Exploits.URLs | string | URLs associated to the threat separated by commas | +| ZeroFox.Exploits.CreatedAt | string | Date in which the ip was found related to a threat. | +| ZeroFox.Exploits.CVECode | string | CVE Code to identify the exploit. | +| ZeroFox.Exploits.URLs | string | URLs associated to the threat separated by commas. | ## Incident Mirroring You can enable incident mirroring between Cortex XSOAR incidents and ZeroFox corresponding events (available from Cortex XSOAR version 6.0.0). To set up the mirroring: - 1. Enable *Fetching incidents* in your instance configuration. Newly fetched incidents will be mirrored in the chosen direction. However, this selection does not affect existing incidents. diff --git a/Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.py b/Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.py index 6867d6c6946f..8b95a910c9fb 100644 --- a/Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.py +++ b/Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.py @@ -628,9 +628,19 @@ def get_alert_contents(alert: dict[str, Any]) -> dict[str, Any]: "AlertType": alert.get("alert_type"), "OffendingContentURL": alert.get("offending_content_url"), "Assignee": alert.get("assignee"), + "Entity": { + "ID": get_nested_key(alert, ["entity", "id"]), + "Name": get_nested_key(alert, ["entity", "name"]), + "Image": get_nested_key(alert, ["entity", "image"]), + }, "EntityID": get_nested_key(alert, ["entity", "id"]), "EntityName": get_nested_key(alert, ["entity", "name"]), "EntityImage": get_nested_key(alert, ["entity", "image"]), + "EntityTerm": { + "ID": get_nested_key(alert, ["entity_term", "id"]), + "Name": get_nested_key(alert, ["entity_term", "name"]), + "Deleted": get_nested_key(alert, ["entity_term", "deleted"]), + }, "EntityTermID": get_nested_key(alert, ["entity_term", "id"]), "EntityTermName": get_nested_key(alert, ["entity_term", "name"]), "EntityTermDeleted": get_nested_key(alert, ["entity_term", "deleted"]), @@ -638,6 +648,14 @@ def get_alert_contents(alert: dict[str, Any]) -> dict[str, Any]: "ID": alert.get("id"), "ProtectedAccount": alert.get("protected_account"), "RiskRating": severity_num_to_string(int(alert.get("severity", ""))), + "Perpetrator": { + "Name": get_nested_key(alert, ["perpetrator", "name"]), + "Url": get_nested_key(alert, ["perpetrator", "url"]), + "TimeStamp": get_nested_key(alert, ["perpetrator", "timestamp"]), + "Type": get_nested_key(alert, ["perpetrator", "type"]), + "ID": get_nested_key(alert, ["perpetrator", "id"]), + "Network": get_nested_key(alert, ["perpetrator", "network"]), + }, "PerpetratorName": get_nested_key(alert, ["perpetrator", "name"]), "PerpetratorUrl": get_nested_key(alert, ["perpetrator", "url"]), "PerpetratorTimeStamp": get_nested_key( diff --git a/Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.yml b/Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.yml index 88460f498074..f856d432218d 100644 --- a/Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.yml +++ b/Packs/ZeroFox/Integrations/ZeroFox/ZeroFox.yml @@ -113,13 +113,13 @@ script: description: The ID of the rule group. type: Number - contextPath: ZeroFox.Alert.Status - description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested", or "Whitelisted". + description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". type: String - contextPath: ZeroFox.Alert.Timestamp - description: The date-time string when an the alert was created, in ISO-8601 format. + description: The date-time string when an alert was created, in ISO-8601 format. type: Date - contextPath: ZeroFox.Alert.RuleName - description: The name of the rule on which an alert was created. Outputs "null" if the rule was deleted. + description: The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. type: String - contextPath: ZeroFox.Alert.LastModified description: The date and time at which an alert was last modified. @@ -140,7 +140,7 @@ script: description: The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, (account information or an incoming or outgoing content), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. type: String - contextPath: ZeroFox.Alert.Notes - description: Notes made on an alert by the user. + description: Notes made on an alert. type: String - contextPath: ZeroFox.Alert.RuleID description: The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. @@ -161,11 +161,101 @@ script: name: username required: true outputs: + - contextPath: ZeroFox.Alert.AlertType + description: The type of an alert. + type: String + - contextPath: ZeroFox.Alert.OffendingContentURL + description: The URL to the site containing content that triggered an alert. + type: String + - contextPath: ZeroFox.Alert.Assignee + description: The user to which an alert is assigned. + type: String + - contextPath: ZeroFox.Alert.Entity.ID + description: The ID of the entity corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.Entity.Name + description: The name of the entity corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.Entity.Image + description: The URL to the profile image of the entity on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.ID + description: The ID of the entity term corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.EntityTerm.Name + description: The name of the entity term corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.Deleted + description: Whether an entity term was deleted. + type: Boolean + - contextPath: ZeroFox.Alert.ContentCreatedAt + description: The date-time string indicating when the alerted content was created, in ISO-8601 format. + type: Date - contextPath: ZeroFox.Alert.ID description: The ID of an alert. type: Number - - contextPath: ZeroFox.Alert.Assignee - description: The user to which an alert is assigned. + - contextPath: ZeroFox.Alert.RiskRating + description: The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Name + description: For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.URL + description: The URL at which you can view the basic details of the perpetrator. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.Timestamp + description: The timestamp of a post created by a perpetrator. + type: Date + - contextPath: ZeroFox.Alert.Perpetrator.Type + description: The type of perpetrator on which an alert was created. Can be an account, page, or post. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.ID + description: The ZeroFox resource ID of the alert perpetrator. + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Network + description: The network containing the offending content. + type: String + - contextPath: ZeroFox.Alert.RuleGroupID + description: The ID of the rule group. + type: Number + - contextPath: ZeroFox.Alert.Status + description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". + type: String + - contextPath: ZeroFox.Alert.Timestamp + description: The date-time string when an alert was created, in ISO-8601 format. + type: Date + - contextPath: ZeroFox.Alert.RuleName + description: The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: String + - contextPath: ZeroFox.Alert.LastModified + description: The date and time at which an alert was last modified. + type: Date + - contextPath: ZeroFox.Alert.DarkwebTerm + description: Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. + type: String + - contextPath: ZeroFox.Alert.Reviewed + description: Whether an alert was reviewed. + type: Boolean + - contextPath: ZeroFox.Alert.Escalated + description: Whether an alert was escalated. + type: Boolean + - contextPath: ZeroFox.Alert.Network + description: The network on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.ProtectedSocialObject + description: The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, (account information or an incoming or outgoing content), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. + type: String + - contextPath: ZeroFox.Alert.Notes + description: Notes made on an alert. + type: String + - contextPath: ZeroFox.Alert.RuleID + description: The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: Number + - contextPath: ZeroFox.Alert.Tags + description: A list of an alert's tags. + type: String + - contextPath: ZeroFox.Alert.EntityAccount + description: The account associated with the entity. type: String - name: zerofox-close-alert description: Closes an alert. @@ -174,11 +264,101 @@ script: name: alert_id required: true outputs: + - contextPath: ZeroFox.Alert.AlertType + description: The type of an alert. + type: String + - contextPath: ZeroFox.Alert.OffendingContentURL + description: The URL to the site containing content that triggered an alert. + type: String + - contextPath: ZeroFox.Alert.Assignee + description: The user to which an alert is assigned. + type: String + - contextPath: ZeroFox.Alert.Entity.ID + description: The ID of the entity corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.Entity.Name + description: The name of the entity corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.Entity.Image + description: The URL to the profile image of the entity on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.ID + description: The ID of the entity term corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.EntityTerm.Name + description: The name of the entity term corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.Deleted + description: Whether an entity term was deleted. + type: Boolean + - contextPath: ZeroFox.Alert.ContentCreatedAt + description: The date-time string indicating when the alerted content was created, in ISO-8601 format. + type: Date - contextPath: ZeroFox.Alert.ID description: The ID of an alert. type: Number + - contextPath: ZeroFox.Alert.RiskRating + description: The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Name + description: For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.URL + description: The URL at which you can view the basic details of the perpetrator. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.Timestamp + description: The timestamp of a post created by a perpetrator. + type: Date + - contextPath: ZeroFox.Alert.Perpetrator.Type + description: The type of perpetrator on which an alert was created. Can be an account, page, or post. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.ID + description: The ZeroFox resource ID of the alert perpetrator. + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Network + description: The network containing the offending content. + type: String + - contextPath: ZeroFox.Alert.RuleGroupID + description: The ID of the rule group. + type: Number - contextPath: ZeroFox.Alert.Status - description: The status of an alert. + description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". + type: String + - contextPath: ZeroFox.Alert.Timestamp + description: The date-time string when an alert was created, in ISO-8601 format. + type: Date + - contextPath: ZeroFox.Alert.RuleName + description: The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: String + - contextPath: ZeroFox.Alert.LastModified + description: The date and time at which an alert was last modified. + type: Date + - contextPath: ZeroFox.Alert.DarkwebTerm + description: Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. + type: String + - contextPath: ZeroFox.Alert.Reviewed + description: Whether an alert was reviewed. + type: Boolean + - contextPath: ZeroFox.Alert.Escalated + description: Whether an alert was escalated. + type: Boolean + - contextPath: ZeroFox.Alert.Network + description: The network on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.ProtectedSocialObject + description: The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, (account information or an incoming or outgoing content), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. + type: String + - contextPath: ZeroFox.Alert.Notes + description: Notes made on an alert. + type: String + - contextPath: ZeroFox.Alert.RuleID + description: The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: Number + - contextPath: ZeroFox.Alert.Tags + description: A list of an alert's tags. + type: String + - contextPath: ZeroFox.Alert.EntityAccount + description: The account associated with the entity. type: String - name: zerofox-alert-request-takedown description: Requests a takedown of a specified alert. @@ -187,11 +367,101 @@ script: name: alert_id required: true outputs: + - contextPath: ZeroFox.Alert.AlertType + description: The type of an alert. + type: String + - contextPath: ZeroFox.Alert.OffendingContentURL + description: The URL to the site containing content that triggered an alert. + type: String + - contextPath: ZeroFox.Alert.Assignee + description: The user to which an alert is assigned. + type: String + - contextPath: ZeroFox.Alert.Entity.ID + description: The ID of the entity corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.Entity.Name + description: The name of the entity corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.Entity.Image + description: The URL to the profile image of the entity on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.ID + description: The ID of the entity term corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.EntityTerm.Name + description: The name of the entity term corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.Deleted + description: Whether an entity term was deleted. + type: Boolean + - contextPath: ZeroFox.Alert.ContentCreatedAt + description: The date-time string indicating when the alerted content was created, in ISO-8601 format. + type: Date - contextPath: ZeroFox.Alert.ID description: The ID of an alert. type: Number + - contextPath: ZeroFox.Alert.RiskRating + description: The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Name + description: For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.URL + description: The URL at which you can view the basic details of the perpetrator. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.Timestamp + description: The timestamp of a post created by a perpetrator. + type: Date + - contextPath: ZeroFox.Alert.Perpetrator.Type + description: The type of perpetrator on which an alert was created. Can be an account, page, or post. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.ID + description: The ZeroFox resource ID of the alert perpetrator. + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Network + description: The network containing the offending content. + type: String + - contextPath: ZeroFox.Alert.RuleGroupID + description: The ID of the rule group. + type: Number - contextPath: ZeroFox.Alert.Status - description: The status of an alert. + description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". + type: String + - contextPath: ZeroFox.Alert.Timestamp + description: The date-time string when an alert was created, in ISO-8601 format. + type: Date + - contextPath: ZeroFox.Alert.RuleName + description: The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: String + - contextPath: ZeroFox.Alert.LastModified + description: The date and time at which an alert was last modified. + type: Date + - contextPath: ZeroFox.Alert.DarkwebTerm + description: Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. + type: String + - contextPath: ZeroFox.Alert.Reviewed + description: Whether an alert was reviewed. + type: Boolean + - contextPath: ZeroFox.Alert.Escalated + description: Whether an alert was escalated. + type: Boolean + - contextPath: ZeroFox.Alert.Network + description: The network on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.ProtectedSocialObject + description: The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, (account information or an incoming or outgoing content), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. + type: String + - contextPath: ZeroFox.Alert.Notes + description: Notes made on an alert. + type: String + - contextPath: ZeroFox.Alert.RuleID + description: The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: Number + - contextPath: ZeroFox.Alert.Tags + description: A list of an alert's tags. + type: String + - contextPath: ZeroFox.Alert.EntityAccount + description: The account associated with the entity. type: String - name: zerofox-modify-alert-tags description: Adds tags to and or removes tags from a specified alert. @@ -269,7 +539,7 @@ script: description: The ID of the rule group. type: Number - contextPath: ZeroFox.Alert.Status - description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested", or "Whitelisted". + description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". type: String - contextPath: ZeroFox.Alert.Timestamp description: The date-time string when an alert was created, in ISO-8601 format. @@ -519,75 +789,255 @@ script: - contextPath: ZeroFox.Alert.EntityAccount description: The account associated with the entity. type: String - - name: zerofox-create-entity - description: Creates a new entity associated with the company of the authorized user. + - name: zerofox-create-entity + description: Creates a new entity associated with the company of the authorized user. + arguments: + - description: Name of the entity (may be non-unique). + name: name + required: true + secret: false + - default: false + description: |- + Indicates the type of string matching used for comparing entity names + to impersonator names. It must be `true` or `false`. + isArray: false + name: strict_name_matching + - description: |- + Comma-separated list of string tags for tagging the entity. + For example: + label1,label2,label3. + isArray: true + name: tags + - description: The ID of the policy to assign to the new entity. Can be retrieved running the zerofox-get-policy-types command. + name: policy_id + predefined: + - '' + - description: The name of the organization associated with the entity. + name: organization + outputs: + - contextPath: ZeroFox.Entity.Name + description: The name of the entity. + type: String + - contextPath: ZeroFox.Entity.ID + description: The ID of the entity. + type: Number + - contextPath: ZeroFox.StrictNameMatching + description: Indicates the type of string matching used for comparing entity names to impersonator names. + type: Boolean + - contextPath: ZeroFox.Entity.Tags + description: The list of string tags that can be used for tagging the entity. + type: String + - contextPath: ZeroFox.Entity.PolicyID + description: The policy ID of the entity. + type: String + - contextPath: ZeroFox.Entity.Organization + description: The name of the organization associated with the entity. + type: String + - name: zerofox-alert-cancel-takedown + description: Cancels a takedown of a specified alert. + arguments: + - description: The ID of an alert. Can be retrieved running the zerofox-list-alerts command. + name: alert_id + required: true + outputs: + - contextPath: ZeroFox.Alert.AlertType + description: The type of an alert. + type: String + - contextPath: ZeroFox.Alert.OffendingContentURL + description: The URL to the site containing content that triggered an alert. + type: String + - contextPath: ZeroFox.Alert.Assignee + description: The user to which an alert is assigned. + type: String + - contextPath: ZeroFox.Alert.Entity.ID + description: The ID of the entity corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.Entity.Name + description: The name of the entity corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.Entity.Image + description: The URL to the profile image of the entity on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.ID + description: The ID of the entity term corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.EntityTerm.Name + description: The name of the entity term corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.Deleted + description: Whether an entity term was deleted. + type: Boolean + - contextPath: ZeroFox.Alert.ContentCreatedAt + description: The date-time string indicating when the alerted content was created, in ISO-8601 format. + type: Date + - contextPath: ZeroFox.Alert.ID + description: The ID of an alert. + type: Number + - contextPath: ZeroFox.Alert.RiskRating + description: The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Name + description: For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.URL + description: The URL at which you can view the basic details of the perpetrator. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.Timestamp + description: The timestamp of a post created by a perpetrator. + type: Date + - contextPath: ZeroFox.Alert.Perpetrator.Type + description: The type of perpetrator on which an alert was created. Can be an account, page, or post. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.ID + description: The ZeroFox resource ID of the alert perpetrator. + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Network + description: The network containing the offending content. + type: String + - contextPath: ZeroFox.Alert.RuleGroupID + description: The ID of the rule group. + type: Number + - contextPath: ZeroFox.Alert.Status + description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". + type: String + - contextPath: ZeroFox.Alert.Timestamp + description: The date-time string when an alert was created, in ISO-8601 format. + type: Date + - contextPath: ZeroFox.Alert.RuleName + description: The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: String + - contextPath: ZeroFox.Alert.LastModified + description: The date and time at which an alert was last modified. + type: Date + - contextPath: ZeroFox.Alert.DarkwebTerm + description: Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. + type: String + - contextPath: ZeroFox.Alert.Reviewed + description: Whether an alert was reviewed. + type: Boolean + - contextPath: ZeroFox.Alert.Escalated + description: Whether an alert was escalated. + type: Boolean + - contextPath: ZeroFox.Alert.Network + description: The network on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.ProtectedSocialObject + description: The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, (account information or an incoming or outgoing content), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. + type: String + - contextPath: ZeroFox.Alert.Notes + description: Notes made on an alert. + type: String + - contextPath: ZeroFox.Alert.RuleID + description: The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: Number + - contextPath: ZeroFox.Alert.Tags + description: A list of an alert's tags. + type: String + - contextPath: ZeroFox.Alert.EntityAccount + description: The account associated with the entity. + type: String + - name: zerofox-open-alert + description: Opens an alert. arguments: - - description: Name of the entity (may be non-unique). - name: name + - description: The ID of an alert. Can be retrieved running the zerofox-list-alerts command. + name: alert_id required: true - secret: false - - default: false - description: |- - Indicates the type of string matching used for comparing entity names - to impersonator names. It must be `true` or `false`. - isArray: false - name: strict_name_matching - - description: |- - Comma-separated list of string tags for tagging the entity. - For example: - label1,label2,label3. - isArray: true - name: tags - - description: The ID of the policy to assign to the new entity. Can be retrieved running the zerofox-get-policy-types command. - name: policy_id - predefined: - - '' - - description: The name of the organization associated with the entity. - name: organization outputs: - - contextPath: ZeroFox.Entity.Name - description: The name of the entity. + - contextPath: ZeroFox.Alert.AlertType + description: The type of an alert. type: String - - contextPath: ZeroFox.Entity.ID - description: The ID of the entity. + - contextPath: ZeroFox.Alert.OffendingContentURL + description: The URL to the site containing content that triggered an alert. + type: String + - contextPath: ZeroFox.Alert.Assignee + description: The user to which an alert is assigned. + type: String + - contextPath: ZeroFox.Alert.Entity.ID + description: The ID of the entity corresponding to the triggered alert. type: Number - - contextPath: ZeroFox.StrictNameMatching - description: Indicates the type of string matching used for comparing entity names to impersonator names. - type: Boolean - - contextPath: ZeroFox.Entity.Tags - description: The list of string tags that can be used for tagging the entity. + - contextPath: ZeroFox.Alert.Entity.Name + description: The name of the entity corresponding to the triggered alert. type: String - - contextPath: ZeroFox.Entity.PolicyID - description: The policy ID of the entity. + - contextPath: ZeroFox.Alert.Entity.Image + description: The URL to the profile image of the entity on which an alert was created. type: String - - contextPath: ZeroFox.Entity.Organization - description: The name of the organization associated with the entity. + - contextPath: ZeroFox.Alert.EntityTerm.ID + description: The ID of the entity term corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.EntityTerm.Name + description: The name of the entity term corresponding to the triggered alert. type: String - - name: zerofox-alert-cancel-takedown - description: Cancels a takedown of a specified alert. - arguments: - - description: The ID of an alert. Can be retrieved running the zerofox-list-alerts command. - name: alert_id - required: true - outputs: + - contextPath: ZeroFox.Alert.EntityTerm.Deleted + description: Whether an entity term was deleted. + type: Boolean + - contextPath: ZeroFox.Alert.ContentCreatedAt + description: The date-time string indicating when the alerted content was created, in ISO-8601 format. + type: Date - contextPath: ZeroFox.Alert.ID description: The ID of an alert. type: Number - - contextPath: ZeroFox.Alert.Status - description: The status of an alert. + - contextPath: ZeroFox.Alert.RiskRating + description: The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Name + description: For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. type: String - - name: zerofox-open-alert - description: Opens an alert. - arguments: - - description: The ID of an alert. Can be retrieved running the zerofox-list-alerts command. - name: alert_id - required: true - outputs: - - contextPath: ZeroFox.Alert.ID - description: The ID of an alert. + - contextPath: ZeroFox.Alert.Perpetrator.URL + description: The URL at which you can view the basic details of the perpetrator. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.Timestamp + description: The timestamp of a post created by a perpetrator. + type: Date + - contextPath: ZeroFox.Alert.Perpetrator.Type + description: The type of perpetrator on which an alert was created. Can be an account, page, or post. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.ID + description: The ZeroFox resource ID of the alert perpetrator. + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Network + description: The network containing the offending content. + type: String + - contextPath: ZeroFox.Alert.RuleGroupID + description: The ID of the rule group. type: Number - contextPath: ZeroFox.Alert.Status - description: The status of an alert. + description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". + type: String + - contextPath: ZeroFox.Alert.Timestamp + description: The date-time string when an alert was created, in ISO-8601 format. + type: Date + - contextPath: ZeroFox.Alert.RuleName + description: The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: String + - contextPath: ZeroFox.Alert.LastModified + description: The date and time at which an alert was last modified. + type: Date + - contextPath: ZeroFox.Alert.DarkwebTerm + description: Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. + type: String + - contextPath: ZeroFox.Alert.Reviewed + description: Whether an alert was reviewed. + type: Boolean + - contextPath: ZeroFox.Alert.Escalated + description: Whether an alert was escalated. + type: Boolean + - contextPath: ZeroFox.Alert.Network + description: The network on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.ProtectedSocialObject + description: The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, (account information or an incoming or outgoing content), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. + type: String + - contextPath: ZeroFox.Alert.Notes + description: Notes made on an alert. + type: String + - contextPath: ZeroFox.Alert.RuleID + description: The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: Number + - contextPath: ZeroFox.Alert.Tags + description: A list of an alert's tags. + type: String + - contextPath: ZeroFox.Alert.EntityAccount + description: The account associated with the entity. type: String - name: zerofox-list-entities description: Lists all entities associated with the company of the authorized user. @@ -717,7 +1167,7 @@ script: description: The ID of the rule group. type: Number - contextPath: ZeroFox.Alert.Status - description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested", or "Whitelisted". + description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". type: String - contextPath: ZeroFox.Alert.Timestamp description: The date-time string when an alert was created, in ISO-8601 format. @@ -782,9 +1232,102 @@ script: description: Additional notes to include in submission. type: textArea outputs: + - contextPath: ZeroFox.Alert.AlertType + description: The type of an alert. + type: String + - contextPath: ZeroFox.Alert.OffendingContentURL + description: The URL to the site containing content that triggered an alert. + type: String + - contextPath: ZeroFox.Alert.Assignee + description: The user to which an alert is assigned. + type: String + - contextPath: ZeroFox.Alert.Entity.ID + description: The ID of the entity corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.Entity.Name + description: The name of the entity corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.Entity.Image + description: The URL to the profile image of the entity on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.ID + description: The ID of the entity term corresponding to the triggered alert. + type: Number + - contextPath: ZeroFox.Alert.EntityTerm.Name + description: The name of the entity term corresponding to the triggered alert. + type: String + - contextPath: ZeroFox.Alert.EntityTerm.Deleted + description: Whether an entity term was deleted. + type: Boolean + - contextPath: ZeroFox.Alert.ContentCreatedAt + description: The date-time string indicating when the alerted content was created, in ISO-8601 format. + type: Date - contextPath: ZeroFox.Alert.ID - description: The ID of the alert created. + description: The ID of an alert. + type: Number + - contextPath: ZeroFox.Alert.RiskRating + description: The risk rating of an alert. Can be "Critical", "High", "Medium", "Low", or "Info". + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Name + description: For account, post, or page alerts, the perpetrator's social network account display name or the account from which the content was posted. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.URL + description: The URL at which you can view the basic details of the perpetrator. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.Timestamp + description: The timestamp of a post created by a perpetrator. + type: Date + - contextPath: ZeroFox.Alert.Perpetrator.Type + description: The type of perpetrator on which an alert was created. Can be an account, page, or post. + type: String + - contextPath: ZeroFox.Alert.Perpetrator.ID + description: The ZeroFox resource ID of the alert perpetrator. + type: Number + - contextPath: ZeroFox.Alert.Perpetrator.Network + description: The network containing the offending content. + type: String + - contextPath: ZeroFox.Alert.RuleGroupID + description: The ID of the rule group. + type: Number + - contextPath: ZeroFox.Alert.Status + description: The status of an alert. Can be "Open", "Closed", "Takedown:Accepted", "Takedown:Denied", "Takedown:Requested" and "Whitelisted". + type: String + - contextPath: ZeroFox.Alert.Timestamp + description: The date-time string when an alert was created, in ISO-8601 format. + type: Date + - contextPath: ZeroFox.Alert.RuleName + description: The name of the rule on which an alert was created. Outputs "null" if the rule has been deleted. + type: String + - contextPath: ZeroFox.Alert.LastModified + description: The date and time at which an alert was last modified. + type: Date + - contextPath: ZeroFox.Alert.DarkwebTerm + description: Details about the dark web term on which an alert was created. Outputs "null" if the alert has no details. + type: String + - contextPath: ZeroFox.Alert.Reviewed + description: Whether an alert was reviewed. + type: Boolean + - contextPath: ZeroFox.Alert.Escalated + description: Whether an alert was escalated. + type: Boolean + - contextPath: ZeroFox.Alert.Network + description: The network on which an alert was created. + type: String + - contextPath: ZeroFox.Alert.ProtectedSocialObject + description: The protected object corresponding to an alert. If the alert occurred on an entity term, the protected object will be an entity term name. If the alert occurred on a protected account, (account information or an incoming or outgoing content), and it was network defined, the protected object will be an account username. If the alert was not network-defined, the protected object will default to the account's display name. Otherwise, the protected account will be an account display name. For impersonation alerts, the protected object is null. + type: String + - contextPath: ZeroFox.Alert.Notes + description: Notes made on an alert. + type: String + - contextPath: ZeroFox.Alert.RuleID + description: The ID of the rule on which an alert was created. Outputs "null" if the rule has been deleted. type: Number + - contextPath: ZeroFox.Alert.Tags + description: A list of an alert's tags. + type: String + - contextPath: ZeroFox.Alert.EntityAccount + description: The account associated with the entity. + type: String deprecated: false execution: false - name: zerofox-search-compromised-domain diff --git a/Packs/ZeroFox/ReleaseNotes/1_2_8.md b/Packs/ZeroFox/ReleaseNotes/1_2_8.md new file mode 100644 index 000000000000..5bd2993121ac --- /dev/null +++ b/Packs/ZeroFox/ReleaseNotes/1_2_8.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### ZeroFox + +- Updated the outputs of the commands related to alerts. diff --git a/Packs/ZeroFox/pack_metadata.json b/Packs/ZeroFox/pack_metadata.json index 1ed826fe5f73..9e3ee0298633 100644 --- a/Packs/ZeroFox/pack_metadata.json +++ b/Packs/ZeroFox/pack_metadata.json @@ -2,7 +2,7 @@ "name": "ZeroFox", "description": "Cloud-based SaaS to detect risks found on social media and digital channels.", "support": "partner", - "currentVersion": "1.2.7", + "currentVersion": "1.2.8", "author": "ZeroFox", "url": "https://www.zerofox.com/contact-us/", "email": "integration-support@zerofox.com", @@ -19,4 +19,4 @@ ], "dependencies": {}, "displayedImages": [] -} +} \ No newline at end of file From e44f83188ffa11967a853e0f9702cfaa36041262 Mon Sep 17 00:00:00 2001 From: Karina Fishman <147307864+karinafishman@users.noreply.github.com> Date: Mon, 26 Feb 2024 12:03:37 +0200 Subject: [PATCH 090/272] Extract indicators from file fix (#33100) * Omri added something * RN added --- ..._Indicators_From_File_-_Generic_v2_4_5.yml | 20 +++++++++++++++++++ ...ators_From_File_-_Generic_v2_4_5_README.md | 4 ++-- Packs/CommonPlaybooks/ReleaseNotes/2_6_15.md | 6 ++++++ Packs/CommonPlaybooks/pack_metadata.json | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 Packs/CommonPlaybooks/ReleaseNotes/2_6_15.md diff --git a/Packs/CommonPlaybooks/Playbooks/playbook-Extract_Indicators_From_File_-_Generic_v2_4_5.yml b/Packs/CommonPlaybooks/Playbooks/playbook-Extract_Indicators_From_File_-_Generic_v2_4_5.yml index e3725a04dec8..440e8a5b3d1b 100644 --- a/Packs/CommonPlaybooks/Playbooks/playbook-Extract_Indicators_From_File_-_Generic_v2_4_5.yml +++ b/Packs/CommonPlaybooks/Playbooks/playbook-Extract_Indicators_From_File_-_Generic_v2_4_5.yml @@ -215,6 +215,15 @@ tasks: right: value: simple: UTF-8 Unicode text + - operator: containsString + left: + value: + simple: inputs.File.Type + iscontext: true + right: + value: + simple: JSON data + ignorecase: true - - operator: notContainsString left: value: @@ -303,6 +312,8 @@ tasks: transformers: - operator: uniq iscontext: true + right: + value: {} continueonerrortype: "" view: |- { @@ -364,6 +375,15 @@ tasks: right: value: simple: UTF-8 Unicode + - operator: containsString + left: + value: + simple: inputs.File.Type + iscontext: true + right: + value: + simple: JSON data + ignorecase: true - - operator: notContainsString left: value: diff --git a/Packs/CommonPlaybooks/Playbooks/playbook-Extract_Indicators_From_File_-_Generic_v2_4_5_README.md b/Packs/CommonPlaybooks/Playbooks/playbook-Extract_Indicators_From_File_-_Generic_v2_4_5_README.md index c3d3f57985e4..8122ca1f3b91 100644 --- a/Packs/CommonPlaybooks/Playbooks/playbook-Extract_Indicators_From_File_-_Generic_v2_4_5_README.md +++ b/Packs/CommonPlaybooks/Playbooks/playbook-Extract_Indicators_From_File_-_Generic_v2_4_5_README.md @@ -33,11 +33,11 @@ This playbook does not use any integrations. ### Scripts -* ExtractIndicatorsFromTextFile -* ConvertFile * ReadPDFFileV2 * ExtractIndicatorsFromWordFile +* ExtractIndicatorsFromTextFile * SetAndHandleEmpty +* ConvertFile ### Commands diff --git a/Packs/CommonPlaybooks/ReleaseNotes/2_6_15.md b/Packs/CommonPlaybooks/ReleaseNotes/2_6_15.md new file mode 100644 index 000000000000..0162983629ac --- /dev/null +++ b/Packs/CommonPlaybooks/ReleaseNotes/2_6_15.md @@ -0,0 +1,6 @@ + +#### Playbooks + +##### Extract Indicators From File - Generic v2 + +- Added a new filter for json file. diff --git a/Packs/CommonPlaybooks/pack_metadata.json b/Packs/CommonPlaybooks/pack_metadata.json index 8a256d0b7ad8..61807f48ac96 100644 --- a/Packs/CommonPlaybooks/pack_metadata.json +++ b/Packs/CommonPlaybooks/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Playbooks", "description": "Frequently used playbooks pack.", "support": "xsoar", - "currentVersion": "2.6.14", + "currentVersion": "2.6.15", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 7d589973912358fb191860b31732b5ba4be537c9 Mon Sep 17 00:00:00 2001 From: israelpoli <72099621+israelpoli@users.noreply.github.com> Date: Mon, 26 Feb 2024 12:34:04 +0200 Subject: [PATCH 091/272] revert the nightly in gitlab on-push (#33099) * revert the nightly in gitlab on-push * remove when --------- Co-authored-by: Adi Bamberger Edri <72088126+BEAdi@users.noreply.github.com> --- .gitlab/ci/.gitlab-ci.on-push.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab/ci/.gitlab-ci.on-push.yml b/.gitlab/ci/.gitlab-ci.on-push.yml index 4d462e71cdd0..18909754fdad 100644 --- a/.gitlab/ci/.gitlab-ci.on-push.yml +++ b/.gitlab/ci/.gitlab-ci.on-push.yml @@ -374,6 +374,7 @@ tests_xsoar_server: rules: - !reference [.filter-non-nightly-docker-updates-rule, rules] - if: '$CI_PIPELINE_SOURCE =~ /^(push|contrib)$/' + - if: '$NIGHTLY' parallel: matrix: - INSTANCE_ROLE: From 6f85d28449dc37723d78d0f5ae568d2a1d3e2700 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Mon, 26 Feb 2024 15:04:52 +0200 Subject: [PATCH 092/272] BmcITSM work order support added (#33043) (#33102) * work order * description.md * Empty posiible values removed * package-lock updated * package-lock * validation * docker, vresion * comment issue * flake * flake * Update Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml * Update Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml * Update Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml * Update Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml * Update Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml * Update Packs/BmcITSM/Integrations/BmcITSM/README.md * Update Packs/BmcITSM/Integrations/BmcITSM/README.md * Update Packs/BmcITSM/Integrations/BmcITSM/README.md * Update Packs/BmcITSM/ReleaseNotes/1_0_22.md * Update Packs/BmcITSM/ReleaseNotes/1_0_22.md * Update Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml * Update Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml * Update Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml * Update Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml * Update Packs/BmcITSM/Integrations/BmcITSM/README.md * Update Packs/BmcITSM/Integrations/BmcITSM/README.md * Update Packs/BmcITSM/Integrations/BmcITSM/README.md * Update Packs/BmcITSM/Integrations/BmcITSM/README.md * Update Packs/BmcITSM/Integrations/BmcITSM/README.md * Update Packs/BmcITSM/Integrations/BmcITSM/README.md * Palo comments resolved * resolving issues * spaces removed * test fixed --------- Co-authored-by: dberezovik <103488527+dberezovik@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> Co-authored-by: Judah Schwartz --- Packs/BmcITSM/.secrets-ignore | 2 +- .../IncidentFields/BMC_Display_ID.json | 3 +- .../IncidentFields/BMC_Request_ID.json | 3 +- .../IncidentFields/BMC_Status_Reason.json | 16 +- .../BmcITSM/IncidentFields/BMC_Submitter.json | 3 +- .../BmcITSM/IncidentFields/BMC_VIP_Flag.json | 3 +- .../BmcITSM/IncidentTypes/BMC_Work_Order.json | 29 + Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py | 358 +++ .../BmcITSM/Integrations/BmcITSM/BmcITSM.yml | 713 +++--- .../BmcITSM/BmcITSM_description.md | 3 +- .../Integrations/BmcITSM/BmcITSM_test.py | 299 +++ Packs/BmcITSM/Integrations/BmcITSM/README.md | 685 ++++-- .../BmcITSM/test_data/create_work_order.json | 14 + .../BmcITSM/test_data/get_work_order.json | 215 ++ .../BmcITSM/test_data/list_support_group.json | 160 ++ .../test_data/list_support_group_filter.json | 83 + .../test_data/list_tickets_work_order.json | 226 ++ .../test_data/list_work_order_template.json | 522 ++++ .../list_work_order_template_filter.json | 264 +++ Packs/BmcITSM/README.md | 2 +- Packs/BmcITSM/ReleaseNotes/1_0_22.md | 29 + Packs/BmcITSM/pack_metadata.json | 4 +- package-lock.json | 2089 +++++++++-------- 23 files changed, 4022 insertions(+), 1703 deletions(-) create mode 100644 Packs/BmcITSM/IncidentTypes/BMC_Work_Order.json create mode 100644 Packs/BmcITSM/Integrations/BmcITSM/test_data/create_work_order.json create mode 100644 Packs/BmcITSM/Integrations/BmcITSM/test_data/get_work_order.json create mode 100644 Packs/BmcITSM/Integrations/BmcITSM/test_data/list_support_group.json create mode 100644 Packs/BmcITSM/Integrations/BmcITSM/test_data/list_support_group_filter.json create mode 100644 Packs/BmcITSM/Integrations/BmcITSM/test_data/list_tickets_work_order.json create mode 100644 Packs/BmcITSM/Integrations/BmcITSM/test_data/list_work_order_template.json create mode 100644 Packs/BmcITSM/Integrations/BmcITSM/test_data/list_work_order_template_filter.json create mode 100644 Packs/BmcITSM/ReleaseNotes/1_0_22.md diff --git a/Packs/BmcITSM/.secrets-ignore b/Packs/BmcITSM/.secrets-ignore index 242bec54188d..e0820e1b4b4c 100644 --- a/Packs/BmcITSM/.secrets-ignore +++ b/Packs/BmcITSM/.secrets-ignore @@ -1,3 +1,3 @@ company1@xsoar.com http://www.company1.com -info@bmc.com \ No newline at end of file +info@bmc.com diff --git a/Packs/BmcITSM/IncidentFields/BMC_Display_ID.json b/Packs/BmcITSM/IncidentFields/BMC_Display_ID.json index 58b52c937640..d9d637fb6bd1 100644 --- a/Packs/BmcITSM/IncidentFields/BMC_Display_ID.json +++ b/Packs/BmcITSM/IncidentFields/BMC_Display_ID.json @@ -27,7 +27,8 @@ "BMC Incident", "BMC Service Request", "BMC Problem – Known Error", - "BMC Task" + "BMC Task", + "BMC Work Order" ], "associatedToAll": false, "unmapped": false, diff --git a/Packs/BmcITSM/IncidentFields/BMC_Request_ID.json b/Packs/BmcITSM/IncidentFields/BMC_Request_ID.json index 8a6d8d2a5668..45a7bea79f0d 100644 --- a/Packs/BmcITSM/IncidentFields/BMC_Request_ID.json +++ b/Packs/BmcITSM/IncidentFields/BMC_Request_ID.json @@ -27,7 +27,8 @@ "BMC Problem Investigation incident", "BMC Problem – Known Error", "BMC Service Request", - "BMC Task" + "BMC Task", + "BMC Work Order" ], "associatedToAll": false, "unmapped": false, diff --git a/Packs/BmcITSM/IncidentFields/BMC_Status_Reason.json b/Packs/BmcITSM/IncidentFields/BMC_Status_Reason.json index a224f67652a0..8983b9d41025 100644 --- a/Packs/BmcITSM/IncidentFields/BMC_Status_Reason.json +++ b/Packs/BmcITSM/IncidentFields/BMC_Status_Reason.json @@ -95,7 +95,18 @@ "Pending PIR", "Funding Not Available", "Pending Infrastructure Change", - "Pending Third Party Vendor" + "Pending Third Party Vendor", + "Initial Status", + "Awaiting Request Assignee", + "Client Additional Information Requested", + "Third Party Vendor Action Required", + "Infrastructure Change", + "Work not started", + "Cancelled by Requester", + "Cancelled by Support", + "Customer Close", + "System Close", + "System Close with Issues" ], "useAsKpi": false, "locked": false, @@ -110,7 +121,8 @@ "BMC Problem Investigation incident", "BMC Problem – Known Error", "BMC Service Request", - "BMC Task" + "BMC Task", + "BMC Work Order" ], "associatedToAll": false, "unmapped": false, diff --git a/Packs/BmcITSM/IncidentFields/BMC_Submitter.json b/Packs/BmcITSM/IncidentFields/BMC_Submitter.json index d6ffa3bdee28..009361b8c73f 100644 --- a/Packs/BmcITSM/IncidentFields/BMC_Submitter.json +++ b/Packs/BmcITSM/IncidentFields/BMC_Submitter.json @@ -27,7 +27,8 @@ "BMC Problem Investigation incident", "BMC Problem – Known Error", "BMC Service Request", - "BMC Task" + "BMC Task", + "BMC Work Order" ], "associatedToAll": false, "unmapped": false, diff --git a/Packs/BmcITSM/IncidentFields/BMC_VIP_Flag.json b/Packs/BmcITSM/IncidentFields/BMC_VIP_Flag.json index 28cd7c8fa2b8..a75e5952826d 100644 --- a/Packs/BmcITSM/IncidentFields/BMC_VIP_Flag.json +++ b/Packs/BmcITSM/IncidentFields/BMC_VIP_Flag.json @@ -23,7 +23,8 @@ "hidden": false, "openEnded": false, "associatedTypes": [ - "BMC Incident" + "BMC Incident", + "BMC Work Order" ], "associatedToAll": false, "unmapped": false, diff --git a/Packs/BmcITSM/IncidentTypes/BMC_Work_Order.json b/Packs/BmcITSM/IncidentTypes/BMC_Work_Order.json new file mode 100644 index 000000000000..b6379ae243e2 --- /dev/null +++ b/Packs/BmcITSM/IncidentTypes/BMC_Work_Order.json @@ -0,0 +1,29 @@ +{ + "id": "BMC Work Order", + "version": -1, + "vcShouldIgnore": false, + "locked": false, + "name": "BMC Work Order", + "prevName": "BMC Work Order", + "color": "#229BDC", + "hours": 0, + "days": 0, + "weeks": 0, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "disabled": false, + "reputationCalc": 0, + "onChangeRepAlg": 0, + "layout": "BMC ITSM Layout", + "detached": false, + "extractSettings": { + "mode": "Specific", + "fieldCliNameToExtractSettings": {} + }, + "fromVersion": "6.2.0" +} \ No newline at end of file diff --git a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py index 9e844511c652..ecb3b8105e6f 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py +++ b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.py @@ -13,6 +13,7 @@ TASK = "task" PROBLEM_INVESTIGATION = "problem investigation" KNOWN_ERROR = "known error" +WORK_ORDER = "work order" SERVICE_REQUEST_CONTEXT_MAPPER = { "SysRequestID": "RequestID", @@ -100,6 +101,24 @@ "View Access": "ViewAccess", "Stastus_Reason": "StatusReason", # The product has typo in the response } + +WORK_ORDER_CONTEXT_MAPPER = { + "Request ID": "RequestID", + "Work Order ID": "DisplayID", + "Submit Date": "CreateDate", + "Status": "Status", + "Description": "Summary", + "Last Modified Date": "LastModifiedDate", + "Detailed Description": "Details", + "VIP": "VIP", + "Reported Source": "ReportedSource", + "Status Reason": "StatusReason", + "ASCHG": "Assignee", + "ASGRP": "Assigned Group", + "ASCPY": "Assigned Support Company", + "Support Organization": "Assigned Support Organization", +} + COMMON_PROPERTIES = [ "Submitter", "Urgency", @@ -136,6 +155,7 @@ TASK: "TMS:Task", PROBLEM_INVESTIGATION: "PBM:ProblemInterface", KNOWN_ERROR: "PBM:KnownErrorInterface", + WORK_ORDER: "WOI:WorkOrderInterface", } TICKET_TYPE_TO_DELETE_FORM = { @@ -144,6 +164,7 @@ TASK: "TMS:Task", PROBLEM_INVESTIGATION: "PBM:Problem Investigation", KNOWN_ERROR: "PBM:Known Error", + WORK_ORDER: "WOI:WorkOrderInterface", } TICKET_TYPE_TO_STATUS_FIELD = { @@ -153,6 +174,7 @@ PROBLEM_INVESTIGATION: "Investigation Status", KNOWN_ERROR: "Known Error Status", TASK: "Status", + WORK_ORDER: "Status", } TICKET_TYPE_TO_CONTEXT_MAPPER = { @@ -162,6 +184,7 @@ TASK: TASK_CONTEXT_MAPPER, PROBLEM_INVESTIGATION: PROBLEM_INVESTIGATION_CONTEXT_MAPPER, KNOWN_ERROR: KNOWN_ERROR_CONTEXT_MAPPER, + WORK_ORDER: WORK_ORDER_CONTEXT_MAPPER, } TICKET_TYPE_TO_STATUS_KEY = { @@ -171,6 +194,7 @@ TASK: "Status", PROBLEM_INVESTIGATION: "Investigation Status", KNOWN_ERROR: "Known Error Status", + WORK_ORDER: "Status", } TICKET_TYPE_TO_SUMMARY_KEY = { @@ -180,6 +204,7 @@ TASK: "Summary", PROBLEM_INVESTIGATION: "Description", KNOWN_ERROR: "Description", + WORK_ORDER: "Description", } TICKET_TYPE_TO_REQUEST_ID_KEY = { @@ -189,6 +214,7 @@ TASK: "Task ID", PROBLEM_INVESTIGATION: "Request ID", KNOWN_ERROR: "Request ID", + WORK_ORDER: "Work Order ID", } TICKET_TYPE_TO_CREATE_QUERY = { @@ -198,6 +224,7 @@ TASK: "values(Task ID,Create Date)", PROBLEM_INVESTIGATION: "values(Request ID,Problem Investigation ID,Create Date)", KNOWN_ERROR: "values(Request ID,Known Error ID,Create Date)", + WORK_ORDER: "values(Request ID,WorkOrder_ID,Create Date)", } FIELD_DELIMITER = ";" @@ -209,6 +236,7 @@ "TAS": TASK, "PBI": PROBLEM_INVESTIGATION, "PKE": KNOWN_ERROR, + "WO0": WORK_ORDER, } CREATE_CONTEXT_MAPPER = { @@ -223,12 +251,14 @@ "Submit Date": "CreateDate", "Create Date": "CreateDate", "Task ID": "DisplayID", + "WorkOrder_ID": "DisplayID", } TICKET_TYPE_TO_DISPLAY_ID = { INCIDENT: "Incident Number", PROBLEM_INVESTIGATION: "Problem Investigation ID", KNOWN_ERROR: "Known Error ID", + WORK_ORDER: "Work Order ID", } ID_QUERY_MAPPER_KEY = "IDS" EQUAL_QUERY_MAPPER_KEY = "EQUAL" @@ -246,6 +276,7 @@ TASK, PROBLEM_INVESTIGATION, KNOWN_ERROR, + WORK_ORDER, ] TICKET_INCIDENT_TYPES = [ "BMC Change-Request", @@ -254,6 +285,7 @@ "BMC Problem Investigation incident", "BMC Service Request", "BMC Task", + "BMC Work Order", ] TICKET_TYPE_TO_INCIDENT_TYPE = { @@ -263,6 +295,7 @@ PROBLEM_INVESTIGATION: "BMC Problem Investigation incident", KNOWN_ERROR: "BMC Problem – Known Error", TASK: "BMC Task", + WORK_ORDER: "BMC Work Order", } MIRRORING_COMMON_FIELDS = [ @@ -282,6 +315,7 @@ TASK: ["Priority"], PROBLEM_INVESTIGATION: ["Priority"], KNOWN_ERROR: ["Priority"], + WORK_ORDER: ["Priority"], } MIRROR_DIRECTION_MAPPING = { @@ -1280,6 +1314,143 @@ def update_known_error_request( return response + def create_work_order_request( + self, + template_guid: str, + first_name: str, + last_name: str, + customer_person_id: str, + customer_first_name: str, + customer_last_name: str, + customer_company: str, + summary: str, + detailed_description: str, + status: str, + priority: str, + work_order_type: str, + location_company: str, + scedulded_start_date: str, + scedulded_end_date: str, + **additional_fields, + ) -> Dict[str, Any]: + """ + Create work order request. + + Args: + template_guid (str): Work order template GUID. + first_name (str): Requester first name. + last_name (str): Requester last name. + customer_person_id (str): Customer person id (in case first/last pair in ambiguous), + customer_first_name (str): Customer first name + customer_last_name (str): Customer last name + customer_company (str): Customer company + summary (str): Work order summary. + detailed_description (str): Work order detailed descirption. + status (str): Ticket status. + priority (str): Ticket priority. + work_order_type (str): Work order type. + location_company (str): Company assoiciated with work order process. + scedulded_start_date (str): Schedulded start date. + scedulded_end_date (str): Schedulded end date. + + Returns: + Dict[str, Any]: API respnse from BmcITSM. + """ + + properties = remove_empty_elements({ + "TemplateID": template_guid, + "First Name": first_name, + "Last Name": last_name, + "Customer Person ID": customer_person_id, + "Customer First Name": customer_first_name, + "Customer Last Name": customer_last_name, + "Customer Company": customer_company, + "Summary": summary, + "Detailed Description": detailed_description, + "Status": status, + "Priority": priority, + "Work Order Type": work_order_type, + "Location Company": location_company, + "Scheduled Start Date": scedulded_start_date, + "Scheduled End Date": scedulded_end_date, + "z1D_Action": "CREATE", + **additional_fields, + }) + data = {"values": properties} + params = {"fields": TICKET_TYPE_TO_CREATE_QUERY[WORK_ORDER]} + response = self._http_request("POST", + "arsys/v1/entry/WOI:WorkOrderInterface_Create", + json_data=data, + params=params) + return response + + def update_work_order_request( + self, + request_id: str, + summary: str, + detailed_description: str, + status: str, + status_reason: str, + priority: str, + work_order_type: str, + company: str, + assignee: str, + support_organization: str, + support_group_name: str, + location_company: str, + scedulded_start_date: str, + schedulded_end_date: str, + **additional_fields, + ): + """ + Work order update request. + + Args: + request_id (str): Work order request ID. + summary (str): Work order summary. + detailed_description (str): Work order details. + status (str): Work order status. + status_reason (str): The reason for changing the status. + priority (str): Work order priority. + work_order_type (str): Work order type. + company (str): Work order company. + assignee (str): Assignee. + support_organization (str): Support organization. + support_group_name (str): Support group name. + location_company (str): Company assoiciated with ticet process. + scedulded_start_date (str): Schedulded start date. + scedulded_end_date (str): Schedulded end date. + Returns: + str: API respnse from BmcITSM. + """ + + properties = remove_empty_elements({ + "Summary": summary, + "Detailed Description": detailed_description, + "Location Company": location_company, + "Status": status, + "Status Reason": status_reason, + "Work Order Type": work_order_type, + "Priority": priority, + "Support Organization": support_organization, + "Support Group Name": support_group_name, + "Company": company, + "Request Assignee": assignee, + "Assigned To": assignee, + "Scheduled Start Date": scedulded_start_date, + "Scheduled End Date": schedulded_end_date, + **additional_fields, + }) + data = {"values": properties} + response = self._http_request( + "PUT", + f"arsys/v1/entry/WOI:WorkOrder/{request_id}", + json_data=data, + resp_type="text", + ) + + return response + def list_command( client: Client, @@ -2513,6 +2684,186 @@ def known_error_update_command(client: Client, args: Dict[str, Any]) -> CommandR return command_results +def support_group_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: + """List BmcITSM support groups. + + Args: + client (Client): BmcITSM API client. + args (Dict[str, Any]): command arguments. + + Returns: + CommandResults: Command results with raw response, outputs and readable outputs. + """ + context_output_mapper = { + "Support Group ID": "SupportGroupID", + "Company": "Company", + "Support Organization": "SupportOrganization", + "Support Group Name": "SupportGroupName" + } + + command_results = list_command( + client, + args, + "CTM:Support Group", + context_output_mapper, + header_prefix="List support groups.", + outputs_prefix="BmcITSM.SupportGroup", + outputs_key_field="SupportGroupID", + record_id_key="SupportGroupID", + ) + return command_results + + +def work_order_template_list_command(client: Client, args: Dict[str, Any]) -> CommandResults: + """List BmcITSM work order templates. + + Args: + client (Client): BmcITSM API client. + args (Dict[str, Any]): command arguments. + + Returns: + CommandResults: Command results with raw response, outputs and readable outputs. + """ + context_output_mapper = { + "Request ID": "Id", + "Template Name": "Name", + "GUID": "GUID", + } + + args["ids"] = argToList(args.get("template_ids")) + command_results = list_command( + client, + args, + "WOI:Template", + context_output_mapper, + header_prefix="List work order templates.", + outputs_prefix="BmcITSM.WorkOrderTemplate", + outputs_key_field="Id", + record_id_key="GUID", + ) + return command_results + + +def work_order_create_command(client: Client, args: Dict[str, Any]) -> CommandResults: + """ + Create BmcITSM work order. + + Args: + client (Client): BmcITSM API client. + args (Dict[str, Any]): command arguments. + + Returns: + CommandResults: Command results with raw response, outputs and readable outputs. + """ + template_guid = args.get("template_guid") + first_name = args.get("first_name") + last_name = args.get("last_name") + customer_person_id = args.get("customer_person_id") + customer_first_name = args.get("customer_first_name") + customer_last_name = args.get("customer_last_name") + customer_company = args.get("customer_company") + summary = args.get("summary") + detailed_description = args.get("detailed_description") + status = args.get("status") + priority = args.get("priority") + work_order_type = args.get("work_order_type") + location_company = args.get("location_company") + scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) + scedulded_end_date: datetime = arg_to_datetime(args.get("scedulded_end_date")) + + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + "additional_fields") + response = client.create_work_order_request( + template_guid, + first_name, + last_name, + customer_person_id, + customer_first_name, + customer_last_name, + customer_company, + summary, + detailed_description, + status, + priority, + work_order_type, + location_company, + scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, + scedulded_end_date=scedulded_end_date.isoformat() if scedulded_end_date else None, + **additional_fields, + ) + + outputs = format_create_ticket_outputs(response.get("values")) + # Fixing API returning RequestID in form 000...NNN instead of WO0...NNN + outputs["RequestID"] = "WO0" + outputs["RequestID"][3:] + readable_output = tableToMarkdown("Work order ticket successfully created.", + outputs, + headerTransform=pascalToSpace) + command_results = CommandResults( + outputs_prefix="BmcITSM.WorkOrder", + outputs_key_field="RequestID", + outputs=outputs, + raw_response=response, + readable_output=readable_output, + ) + + return command_results + + +def work_order_update_command(client: Client, args: Dict[str, Any]) -> CommandResults: + """ + Update BmcITSM work order. + + Args: + client (Client): BmcITSM API client. + args (Dict[str, Any]): command arguments. + + Returns: + CommandResults: Command results with raw response, outputs and readable outputs. + """ + + request_id = args.get("request_id") + summary = args.get("summary") + detailed_description = args.get("detailed_description") + status = args.get("status") + status_reason = args.get("status_reason") + priority = args.get("priority") + work_order_type = args.get("work_order_type") + company = args.get("company") + assignee = args.get("assignee") + support_organization = args.get("support_organization") + support_group = args.get("support_group") + location_company = args.get("location_company") + scedulded_start_date: datetime = arg_to_datetime(args.get("scedulded_start_date")) + schedulded_end_date: datetime = arg_to_datetime(args.get("schedulded_end_date")) + + additional_fields = extract_args_from_additional_fields_arg(args.get("additional_fields"), + "additional_fields") + + validate_related_arguments_provided(support_organization=support_organization, support_group=support_group) + + client.update_work_order_request( + request_id, + summary=summary, + detailed_description=detailed_description, + status=status, + status_reason=status_reason, + priority=priority, + work_order_type=work_order_type, + company=company, + assignee=assignee, + support_organization=support_organization, + support_group_name=support_group, + location_company=location_company, + scedulded_start_date=scedulded_start_date.isoformat() if scedulded_start_date else None, + schedulded_end_date=schedulded_end_date.isoformat if schedulded_end_date else None, + **additional_fields, + ) + + command_results = CommandResults(readable_output=f"Work Order: {request_id} was successfully updated.") + + return command_results + + def format_command_output(records: List[dict], mapper: Dict[str, Any], context_data_arranger: Callable = None) -> Dict[str, Any]: @@ -2833,6 +3184,9 @@ def generate_query_filter_mapper_by_args(args: Dict[str, Any], record_id_key: Op "Organization": args.get("organization"), "Company Type": args.get("company_type"), "TaskName": args.get("task_name"), + "Template Name": args.get("template_name"), + "Support Organization": args.get("support_organization"), + "Support Group Name": args.get("support_group"), } return { ID_QUERY_MAPPER_KEY: ids_filter_mapper, @@ -3579,6 +3933,10 @@ def main() -> None: "bmc-itsm-problem-investigation-update": problem_investigation_update_command, "bmc-itsm-known-error-create": known_error_create_command, "bmc-itsm-known-error-update": known_error_update_command, + "bmc-itsm-support-group-list": support_group_list_command, + "bmc-itsm-work-order-template-list": work_order_template_list_command, + "bmc-itsm-work-order-create": work_order_create_command, + "bmc-itsm-work-order-update": work_order_update_command, } if command == "test-module": diff --git a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml index c6677cdfae79..d378dd20956b 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml +++ b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM.yml @@ -4,7 +4,7 @@ commonfields: name: BmcITSM display: BMC Helix ITSM category: Utilities -description: BMC Helix ITSM integration enables customers to manage service request, incident, change request, task, problem investigation and known error tickets. +description: BMC Helix ITSM integration enables customers to manage service request, incident, change request, task, problem investigation, known error and work order tickets. configuration: - name: url display: Server URL @@ -43,6 +43,7 @@ configuration: - change request - problem investigation - known error + - work order - All required: false - name: ticket_status @@ -187,53 +188,33 @@ script: description: A comma-separated list of user IDs. Used as a filtering argument. isArray: true defaultValue: "" - predefined: - - "" - name: query description: 'The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html).' defaultValue: "" - predefined: - - "" - name: limit description: The maximum number of records to retrieve. defaultValue: "50" - predefined: - - "" - name: page_size description: The maximum number of records to retrieve per page. defaultValue: "" - predefined: - - "" - name: page description: The page number of the results to retrieve. defaultValue: "" - predefined: - - "" - name: first_name description: The user first name. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: last_name description: The user first name. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: company description: The user company name. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: department description: The user department name. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: organization description: The user organization name. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: bmc-itsm-company-list description: Retrieves a list of companies from BMC Helix ITSM. The records are retrieved by the query argument or by the filtering arguments. When using filtering arguments, each one defines a 'LIKE' operation and an 'AND' operator is used between them. To see the entire JSON then you can use the raw_response=true at the end of the command. outputs: @@ -251,38 +232,24 @@ script: description: A comma-separated list of company ID. Filtering argument. isArray: true defaultValue: "" - predefined: - - "" - name: query description: 'The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html).' defaultValue: "" - predefined: - - "" - name: limit description: The maximum number of records to retrieve. defaultValue: "50" - predefined: - - "" - name: page_size description: The maximum number of records to retrieve per page. defaultValue: "" - predefined: - - "" - name: page description: The page number of the results to retrieve. defaultValue: "" - predefined: - - "" - name: company description: The user company name. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: company_type description: The user company type. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: bmc-itsm-service-request-definition-list description: Retrieves a list of service request definitions. The records are retrieved by the query argument or by the filtering arguments. When using filtering arguments, each one defines a 'LIKE' operation and an 'AND' operator is used between them. To see the entire JSON then you can use the raw_response=true at the end of the command. outputs: @@ -300,33 +267,21 @@ script: description: A comma-separated list of service request definition IDs. Used as a filtering argument. isArray: true defaultValue: "" - predefined: - - "" - name: query description: 'The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html).' defaultValue: "" - predefined: - - "" - name: limit description: The maximum number of records to retrieve. defaultValue: "50" - predefined: - - "" - name: page_size description: The maximum number of records to retrieve per page. defaultValue: "" - predefined: - - "" - name: page description: The page number of the results to retrieve. defaultValue: "" - predefined: - - "" - name: description description: The service request ticket definition description. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: bmc-itsm-ticket-list description: Retrieves a list of BMC Helix ITSM tickets. The records are retrieved by the query argument or by the filtering arguments. When using filtering arguments, each one defines a 'LIKE' operation and an 'AND' operator is used between them. To see the entire JSON then you can use the raw_response=true at the end of the command. arguments: @@ -341,32 +296,23 @@ script: - change request - problem investigation - known error + - work order - name: query description: 'The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html).' defaultValue: "" - predefined: - - "" - name: limit description: The maximum number of records to retrieve. defaultValue: "50" - predefined: - - "" - name: page_size description: The maximum number of records to retrieve per page. defaultValue: "" - predefined: - - "" - name: page description: The page number of the results to retrieve. defaultValue: "" - predefined: - - "" - name: ticket_ids - description: A comma-separated list of ticket request IDs. Used as a filtering argument. + description: A comma-separated list of ticket request IDs. Used as a filtering argument. Use Display ID for work order type. isArray: true defaultValue: "" - predefined: - - "" - name: status description: The status of the tickets to fetch. Since each ticket type has its own unique set of statuses, select only statuses that match the selected ticket type(s). defaultValue: "" @@ -456,9 +402,6 @@ script: - name: summary description: The ticket summary. Used as a filtering argument. defaultValue: "" - predefined: - - "" - outputs: - contextPath: BmcITSM.Ticket.RequestID description: The ticket ID. @@ -524,28 +467,18 @@ script: description: "The instance ID of the service request ticket. It can be retrieved by executing bmc-itsm-service-request-definition-list command." required: true defaultValue: "" - predefined: - - "" - name: first_name description: The requester first name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. defaultValue: "" - predefined: - - "" - name: last_name description: "The requester last name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together." defaultValue: "" - predefined: - - "" - name: login_id description: The requester login ID. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. defaultValue: "" - predefined: - - "" - name: summary description: The service request ticket summary. defaultValue: "" - predefined: - - "" - name: status description: "The service request ticket status." defaultValue: "" @@ -584,8 +517,6 @@ script: - name: additional_fields description: 'The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field.' defaultValue: "" - predefined: - - "" outputs: - contextPath: BmcITSM.ServiceRequest.RequestID description: The service request ticket unique request ID. @@ -603,18 +534,12 @@ script: description: The unique identifier of the service request ticket to update. required: true defaultValue: "" - predefined: - - "" - name: customer_first_name description: "The customer first name. By default it is determined by the logged in user." defaultValue: "" - predefined: - - "" - name: customer_last_name description: "The customer last name. By default it is determined by the logged in user." defaultValue: "" - predefined: - - "" - name: status description: "The service request ticket status." defaultValue: "" @@ -670,33 +595,21 @@ script: - name: location_company description: The company associated with the service request process. defaultValue: "" - predefined: - - "" - name: region description: The region associated with the company location. defaultValue: "" - predefined: - - "" - name: site_group description: The site group associated with the region. defaultValue: "" - predefined: - - "" - name: site description: The site associated with the site group. defaultValue: "" - predefined: - - "" - name: assignee description: The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: additional_fields description: 'The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field.' defaultValue: "" - predefined: - - "" outputs: [] - name: bmc-itsm-incident-update description: "Update incident ticket." @@ -705,23 +618,15 @@ script: description: The ID of the incident ticket to update. required: true defaultValue: "" - predefined: - - "" - name: first_name description: The customer first name the incident ticket is for. defaultValue: "" - predefined: - - "" - name: last_name description: The customer last name the incident ticket is for. defaultValue: "" - predefined: - - "" - name: summary description: The incident ticket summary. defaultValue: "" - predefined: - - "" - name: service_type description: "The type of the incident ticket." defaultValue: "" @@ -786,53 +691,33 @@ script: - name: detailed_description description: The incident ticket summary. defaultValue: "" - predefined: - - "" - name: company description: The company associated with the requester. By default it is determined by the logged in user. defaultValue: "" - predefined: - - "" - name: assigned_support_company description: The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. defaultValue: "" - predefined: - - "" - name: assigned_support_organization description: The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. defaultValue: "" - predefined: - - "" - name: assigned_group description: The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. defaultValue: "" - predefined: - - "" - name: assignee description: The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: assignee_login_id description: The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. defaultValue: "" - predefined: - - "" - name: region description: The region, which makes up the second tier of the customer’s business organization data structure. defaultValue: "" - predefined: - - "" - name: site_group description: The site group associated with the region. defaultValue: "" - predefined: - - "" - name: site description: The site associated with the site group. defaultValue: "" - predefined: - - "" - name: status_reason description: The reason for updating the ticket status. Required when status is provided. auto: PREDEFINED @@ -871,8 +756,6 @@ script: required: true isArray: true defaultValue: "" - predefined: - - "" - name: ticket_type description: The type of the tickets to delete. required: true @@ -883,6 +766,7 @@ script: - change request - problem investigation - known error + - work order outputs: [] - name: bmc-itsm-incident-create description: "Creates a new incident ticket. An incident is any event that is not part of the standard operation of a service and that causes an interruption to or a reduction in the quality of that service." @@ -891,24 +775,16 @@ script: description: The customer first name the incident ticket is for. required: true defaultValue: "" - predefined: - - "" - name: last_name description: The customer last name the incident ticket is for. required: true defaultValue: "" - predefined: - - "" - name: template_instance_id description: The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The instance ID can be retrieved by executing the bmc-itsm-incident-template-list command. defaultValue: "" - predefined: - - "" - name: summary description: The incident ticket summary. Required when the template_instance_id argument is not provided. defaultValue: "" - predefined: - - "" - name: service_type description: The type of the incident ticket. Required when the template_instance_id argument is not provided. defaultValue: "" @@ -976,53 +852,33 @@ script: - name: details description: The incident ticket detailed description. defaultValue: "" - predefined: - - "" - name: company description: The company associated with the requester. By default it is determined by the logged in user. defaultValue: "" - predefined: - - "" - name: assigned_support_company description: The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. defaultValue: "" - predefined: - - "" - name: assigned_support_organization description: The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. defaultValue: "" - predefined: - - "" - name: assigned_group description: The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. defaultValue: "" - predefined: - - "" - name: assignee description: The full name of the employee the ticket will be assigned to. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: assignee_login_id description: The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: region description: The region associated with the company. defaultValue: "" - predefined: - - "" - name: site_group description: The site group associated with the region. defaultValue: "" - predefined: - - "" - name: site description: The site associated with the site group. defaultValue: "" - predefined: - - "" outputs: - contextPath: BmcITSM.Incident.RequestID description: The incident ticket request ID. @@ -1040,34 +896,22 @@ script: description: The requester first name. required: true defaultValue: "" - predefined: - - "" - name: last_name description: The requester last name. required: true defaultValue: "" - predefined: - - "" - name: customer_first_name description: "The customer first name." defaultValue: "" - predefined: - - "" - name: customer_last_name description: The customer last name. defaultValue: "" - predefined: - - "" - name: summary description: The change request ticket title. Required when the template ID argument is not provided. defaultValue: "" - predefined: - - "" - name: template_id description: "The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The ID can be retrieved by executing the bmc-itsm-change-request-template-list command." defaultValue: "" - predefined: - - "" - name: change_type description: The change request ticket type. Required when the ticket creation is without a template. defaultValue: "" @@ -1140,13 +984,9 @@ script: - name: location_company description: The company associated with the change request process. Required when template ID argument is not provided. defaultValue: - predefined: - - "" - name: additional_fields description: 'The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field.' defaultValue: "" - predefined: - - "" outputs: - contextPath: BmcITSM.ChangeRequest.RequestID description: The change request ticket unique request ID. @@ -1166,18 +1006,12 @@ script: - name: first_name description: "The customer first name the change request ticket is for." defaultValue: "" - predefined: - - "" - name: last_name description: "The customer last name the change request ticket is for." defaultValue: "" - predefined: - - "" - name: summary description: The change request ticket summary. defaultValue: "" - predefined: - - "" - name: change_type description: "The change request ticket type." defaultValue: "" @@ -1250,53 +1084,33 @@ script: - name: additional_fields description: 'The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field.' defaultValue: "" - predefined: - - "" - name: company description: The company associated with the requester. By default it is determined by the logged in user. defaultValue: "" - predefined: - - "" - name: organization description: The organization associated with the requester. defaultValue: "" - predefined: - - "" - name: department description: The department associated with the requester. defaultValue: "" - predefined: - - "" - name: location_company description: The company associated with the change request process. defaultValue: - predefined: - - "" - name: region description: The region associated with the company location. defaultValue: "" - predefined: - - "" - name: site_group description: The site group associated with the region. defaultValue: "" - predefined: - - "" - name: site description: The site associated with the site group. defaultValue: "" - predefined: - - "" - name: support_organization description: The second tier of the change manager’s support organization data structure. defaultValue: "" - predefined: - - "" - name: support_group_name description: The third tier of the change manager’s support organization data structure. defaultValue: "" - predefined: - - "" - name: status_reason description: "The reason for updating the ticket status. Required when status is provided." defaultValue: "" @@ -1336,29 +1150,21 @@ script: - name: details description: The change request ticket details. defaultValue: "" - predefined: - - "" outputs: [] - name: bmc-itsm-task-create - description: "Creates a new task ticket. By splitting cases into individual tasks (assignments), you can focus on one assignment at a time to resolve cases more efficiently. Task ticket type can be attached only to the following ticket types: change request, incident, problem investigation, and known error." + description: "Creates a new task ticket. By splitting cases into individual tasks (assignments), you can focus on one assignment at a time to resolve cases more efficiently. Task ticket type can be attached only to the following ticket types: change request, incident, problem investigation, known error and work order." arguments: - name: template_id description: The instance ID of the template to use. The ID can be retrieved by executing the bmc-itsm-task-template-list command. defaultValue: "" - predefined: - - "" - name: summary description: The task ticket summary. required: true defaultValue: "" - predefined: - - "" - name: details description: The task ticket detailed description. required: true defaultValue: "" - predefined: - - "" - name: root_ticket_type description: The parent ticket type. required: true @@ -1369,17 +1175,14 @@ script: - incident - problem investigation - known error + - work order - name: root_request_id - description: "The request ID of the parent ticket. Can be found in the context output of the bmc-itsm-ticket-list command." + description: "The request ID of the parent ticket. Can be found in the context output of the bmc-itsm-ticket-list command. Use Display ID for work orders." required: true defaultValue: "" - predefined: - - "" - name: root_request_name description: "The display name of the parent ticket in the task ticket. If not provided, the parent ticket displayID is displayed." defaultValue: "" - predefined: - - "" - name: root_request_mode description: "The parent ticket request mode." defaultValue: Real @@ -1426,23 +1229,15 @@ script: description: The company associated with the task process. required: true defaultValue: "" - predefined: - - "" - name: support_company description: The technical support team associated with the company. defaultValue: "" - predefined: - - "" - name: assigned_support_organization description: The organization for the task's support organization. It makes up the second tier of the task’s support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. defaultValue: - predefined: - - "" - name: assigned_support_group description: The group for the task's support organization. It makes up the third tier of the task's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. defaultValue: "" - predefined: - - "" - name: impact description: The task ticket impact. defaultValue: "" @@ -1464,18 +1259,12 @@ script: - name: assignee description: The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: scedulded_start_date description: The task ticket scheduled future start date. For example, in 12 hours, in 7 days. defaultValue: "" - predefined: - - "" - name: scedulded_end_date description: The task ticket scheduled future end date. For example, in 12 hours, in 7 days. defaultValue: "" - predefined: - - "" outputs: - contextPath: BmcITSM.Task.RequestID description: The task ticket unique Request ID. @@ -1493,17 +1282,11 @@ script: description: The ID of the task ticket to update. required: true defaultValue: "" - predefined: - - "" - name: summary description: The task ticket summary. - predefined: - - "" - name: details description: The task ticket detailed description. defaultValue: "" - predefined: - - "" - name: priority description: The task ticket priority. defaultValue: "" @@ -1544,33 +1327,21 @@ script: - name: company description: The company associated with the requester. By default it is determined by the logged in user. defaultValue: "" - predefined: - - "" - name: location_company description: The company associated with the task process. defaultValue: "" - predefined: - - "" - name: support_company description: The technical support team associated with the company. defaultValue: "" - predefined: - - "" - name: assignee description: The full name of the employee the ticket is assigned to. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: assigned_support_organization description: The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. defaultValue: - predefined: - - "" - name: assigned_group description: The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. defaultValue: "" - predefined: - - "" - name: task_type description: "The task ticket type." defaultValue: "" @@ -1586,13 +1357,9 @@ script: - name: scedulded_start_date description: The task ticket scheduled future start date. For example, in 12 hours, in 7 days. defaultValue: "" - predefined: - - "" - name: scedulded_end_date description: The task ticket scheduled future end date. For example, in 12 hours, in 7 days. defaultValue: "" - predefined: - - "" outputs: [] - name: bmc-itsm-problem-investigation-create description: "Creates a problem investigation ticket." @@ -1601,14 +1368,10 @@ script: description: The customer first name the ticket request is for. required: true defaultValue: "" - predefined: - - "" - name: last_name description: The customer last name the ticket request is for. required: true defaultValue: "" - predefined: - - "" - name: status description: The problem investigation ticket status. required: true @@ -1639,13 +1402,9 @@ script: description: The problem investigation ticket summary. required: true defaultValue: "" - predefined: - - "" - name: details description: The detailed description on the problem investigation ticket. defaultValue: "" - predefined: - - "" - name: impact description: The problem investigation ticket impact. required: true @@ -1669,88 +1428,54 @@ script: - name: target_resolution_date description: The future resolution date. For example, in 12 hours, in 7 days. defaultValue: "" - predefined: - - "" - name: company description: The company associated with the requester. By default it is determined by the logged in user. defaultValue: "" - predefined: - - "" - name: region description: The region of the problem investigation location. The arguments region, site_group, and site should be provided together. defaultValue: "" - predefined: - - "" - name: site_group description: The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. defaultValue: "" - predefined: - - "" - name: site description: The site of the problem investigation location. The arguments region, site_group, and site should be provided together. defaultValue: "" - predefined: - - "" - name: assignee description: The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: assignee_pbm_mgr description: The full name of the employee the ticket will be assigned to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: assigned_group_pbm_mgr description: The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. defaultValue: "" - predefined: - - "" - name: support_company_pbm_mgr description: The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. defaultValue: "" - predefined: - - "" - name: support_organization_pbm_mgr description: The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. defaultValue: "" - predefined: - - "" - name: assigned_support_company description: "The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together." defaultValue: "" - predefined: - - "" - name: assigned_support_organization description: The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. defaultValue: - predefined: - - "" - name: assigned_group description: The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. defaultValue: "" - predefined: - - "" - name: investigation_justification description: The justification for the ticket creation. defaultValue: "" - predefined: - - "" - name: temporary_workaround description: The problem workaround. defaultValue: "" - predefined: - - "" - name: resolution description: The ticket resolution. defaultValue: "" - predefined: - - "" - name: additional_fields description: 'The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field.' defaultValue: "" - predefined: - - "" outputs: - contextPath: BmcITSM.ProblemInvestigation.RequestID description: The problem investigation ticket unique Request ID. @@ -1768,8 +1493,6 @@ script: description: The problem investigation ticket request ID. required: true defaultValue: "" - predefined: - - "" - name: status description: The problem investigation ticket status. defaultValue: "" @@ -1797,8 +1520,6 @@ script: - name: summary description: The problem investigation ticket summary. defaultValue: "" - predefined: - - "" - name: impact description: The problem investigation ticket impact. defaultValue: "" @@ -1820,83 +1541,51 @@ script: - name: target_resolution_date description: The problem investigation ticket target resolution date. For example, in 12 hours, in 7 days. defaultValue: "" - predefined: - - "" - name: details description: The problem investigation ticket detailed description. defaultValue: "" - predefined: - - "" - name: company description: The company associated with the requester. By default it is determined by the logged in user. defaultValue: "" - predefined: - - "" - name: region description: The region of the problem investigation location. The arguments region, site_group, and site should be provided together. defaultValue: "" - predefined: - - "" - name: site_group description: The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. defaultValue: "" - predefined: - - "" - name: site description: The site of the problem investigation location.The arguments region, site_group, and site should be provided together. defaultValue: "" - predefined: - - "" - name: assigned_to description: "The technical support person the ticket is assigned to." defaultValue: "" - predefined: - - "" - name: assigned_group_pbm_mgr description: The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. defaultValue: "" - predefined: - - "" - name: support_company_pbm_mgr description: The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. defaultValue: "" - predefined: - - "" - name: support_organization_pbm_mgr description: The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. defaultValue: "" - predefined: - - "" - name: assigned_support_company description: "The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together." defaultValue: "" - predefined: - - "" - name: assigned_support_organization description: The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. defaultValue: - predefined: - - "" - name: assigned_group description: The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. defaultValue: "" - predefined: - - "" - name: investigation_justification description: The justification for the ticket creation. defaultValue: "" - predefined: - - "" - name: temporary_workaround description: The problem workaround. defaultValue: "" - predefined: - - "" - name: resolution description: The ticket resolution. defaultValue: "" - predefined: - - "" - name: status_reason description: The reason for changing the status. Required when the status argument is provided. defaultValue: "" @@ -1926,14 +1615,10 @@ script: description: The known error ticket summary. required: true defaultValue: "" - predefined: - - "" - name: details description: The known error ticket Detailed description. required: true defaultValue: "" - predefined: - - "" - name: impact description: The known error ticket impact. required: true @@ -1966,74 +1651,46 @@ script: description: Company associated with the Requester. required: true defaultValue: "" - predefined: - - "" - name: target_resolution_date description: Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. required: true defaultValue: "" - predefined: - - "" - name: resolution description: Ticket resolution. defaultValue: "" - predefined: - - "" - name: assigned_group_pbm_mgr description: It makes up the third tier of the Problem Coordinator’s Support Organization data structure. defaultValue: "" - predefined: - - "" - name: support_company_pbm_mgr description: "the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it." defaultValue: "" - predefined: - - "" - name: support_organization_pbm_mgr description: It makes up the second tier of the Problem Coordinator’s Support Organization data structure. defaultValue: "" - predefined: - - "" - name: assigned_support_company description: "The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure." defaultValue: "" - predefined: - - "" - name: assigned_support_organization description: The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. defaultValue: - predefined: - - "" - name: assigned_group description: The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. defaultValue: "" - predefined: - - "" - name: investigation_justification description: The justification for the ticket creation. defaultValue: "" - predefined: - - "" - name: assignee description: The full name of the staff member to whom the ticket will be assigned to. It can be retrieved by using the 'bmc-itsm-user-list' command. defaultValue: "" - predefined: - - "" - name: assignee_pbm_mgr description: The full name of the staff member to whom the ticket will be assign to as the problem coordinator. It can be retrieved by using the 'bmc-itsm-user-list' command. defaultValue: "" - predefined: - - "" - name: temporary_workaround description: Error workaround. defaultValue: "" - predefined: - - "" - name: additional_fields description: 'The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field.' defaultValue: "" - predefined: - - "" outputs: - contextPath: BmcITSM.KnownError.RequestID description: Known Error unique Request ID. @@ -2051,8 +1708,6 @@ script: description: The known error ticket request ID. required: true defaultValue: "" - predefined: - - "" - name: status description: The known error ticket status. defaultValue: "" @@ -2068,13 +1723,9 @@ script: - name: summary description: The known error ticket summary. defaultValue: "" - predefined: - - "" - name: details description: The known error ticket detailed description. defaultValue: "" - predefined: - - "" - name: impact description: The known error ticket impact. defaultValue: "" @@ -2103,53 +1754,33 @@ script: - name: company description: Company associated with the Requester. By default is determined by the logged in user. defaultValue: "" - predefined: - - "" - name: target_resolution_date description: Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. defaultValue: "" - predefined: - - "" - name: resolution description: Ticket resolution. defaultValue: "" - predefined: - - "" - name: assigned_group_pbm_mgr description: It makes up the third tier of the Problem Coordinator’s Support Organization data structure. defaultValue: "" - predefined: - - "" - name: support_company_pbm_mgr description: "the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it." defaultValue: "" - predefined: - - "" - name: support_organization_pbm_mgr description: It makes up the second tier of the Problem Coordinator’s Support Organization data structure. defaultValue: "" - predefined: - - "" - name: assigned_support_company description: "The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure." defaultValue: "" - predefined: - - "" - name: assigned_support_organization description: The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. defaultValue: - predefined: - - "" - name: assigned_group description: The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. defaultValue: "" - predefined: - - "" - name: temporary_workaround description: Error workaround. defaultValue: "" - predefined: - - "" - name: status_reason description: "The reason for changing the status. Required when the status is provided." defaultValue: "" @@ -2164,18 +1795,12 @@ script: - name: assignee description: The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: assignee_pbm_mgr description: The full name of the employee the ticket will be assign to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. defaultValue: "" - predefined: - - "" - name: additional_fields description: 'The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field.' defaultValue: "" - predefined: - - "" outputs: [] - name: bmc-itsm-change-request-template-list description: Lists all change requests ticket templates. Useful for creating change request tickets. The records are retrieved by the query argument or by the filtering arguments. When using filtering arguments, each one defines a 'LIKE' operation and an 'AND' operator is used between them. To see the entire JSON then you can use the raw_response=true at the end of the command. @@ -2184,33 +1809,21 @@ script: description: A comma-separated list of change request template IDs. Used as a filtering argument. isArray: true defaultValue: "" - predefined: - - "" - name: query description: 'The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html).' defaultValue: "" - predefined: - - "" - name: limit description: The maximum number of records to retrieve. defaultValue: "50" - predefined: - - "" - name: page_size description: The maximum number of records to retrieve per page. defaultValue: "" - predefined: - - "" - name: page description: The page number of the results to retrieve. defaultValue: "" - predefined: - - "" - name: description description: The change request ticket description. Used as a filtering argument. defaultValue: "" - predefined: - - "" outputs: - type: String contextPath: BmcITSM.ChangeRequestTemplate.Id @@ -2227,33 +1840,21 @@ script: - name: query description: 'The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html).' defaultValue: "" - predefined: - - "" - name: limit description: The maximum number of records to retrieve. defaultValue: "50" - predefined: - - "" - name: page_size description: The maximum number of records to retrieve per page. defaultValue: "" - predefined: - - "" - name: page description: The page number of the results to retrieve. defaultValue: "" - predefined: - - "" - name: description description: The incident ticket template description. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: template_ids description: A comma-separated list of incident template IDs. Used as a filtering argument. defaultValue: "" - predefined: - - "" outputs: - type: String contextPath: BmcITSM.IncidentTemplate.Id @@ -2270,33 +1871,21 @@ script: - name: query description: 'The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html).' defaultValue: "" - predefined: - - "" - name: limit description: The maximum number of records to retrieve. defaultValue: "50" - predefined: - - "" - name: page_size description: The maximum number of records to retrieve per page. defaultValue: "" - predefined: - - "" - name: page description: The page number of the results to retrieve. defaultValue: "" - predefined: - - "" - name: template_ids description: A comma-separated list of task template IDs. Used as a filtering argument. defaultValue: "" - predefined: - - "" - name: task_name description: The task ticket template name. Used as a filtering argument. defaultValue: "" - predefined: - - "" outputs: - type: String contextPath: BmcITSM.TaskTemplate.Id @@ -2324,6 +1913,292 @@ script: name: lastUpdate description: Gets the list of incidents that were modified since the last update time. Note that this method is here for debugging purposes. The get-modified-remote-data command is used as part of a Mirroring feature, which is available in Cortex XSOAR from version 6.1. name: get-modified-remote-data + - name: bmc-itsm-support-group-list + description: Lists all support groups. Useful for getting possible (Company, Support Organization, Support Group) triplets. + arguments: + - name: limit + description: The maximum number of records to retrieve. + type: String + defaultValue: "50" + - name: page_size + description: The maximum number of records to retrieve per page. + type: String + defaultValue: "" + - name: page + description: The page number of the results to retrieve. + type: String + defaultValue: "" + - name: company + description: Company name. Used as a filtering argument. + type: String + defaultValue: "" + - name: support_organization + description: Support organization name. Used as a filtering argument. + type: String + defaultValue: "" + - name: support_group + description: Support group name. Used as a filtering argument. + type: String + defaultValue: "" + outputs: + - type: String + contextPath: BmcITSM.SupportGroup.SupportGroupID + description: The support group ID. + - type: String + contextPath: BmcITSM.SupportGroup.Company + description: The support company. + - type: String + contextPath: BmcITSM.SupportGroup.SupportOrganization + description: The support organization. + - type: String + contextPath: BmcITSM.SupportGroup.SupportGroupName + description: The support group. + - name: bmc-itsm-work-order-template-list + description: Lists all work order templates. Useful for creating work orders. The records are retrieved by the query argument or by the filtering arguments. When using filtering arguments, each one defines a 'LIKE' operation and an 'AND' operator is used between them. To see the entire JSON, you can use the raw_response=true at the end of the command. + arguments: + - name: query + description: The query to search by. For example, query="Company like \"BMCOpsMonitoring\"". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). + type: String + defaultValue: "" + - name: limit + description: The maximum number of records to retrieve. + type: String + defaultValue: "50" + - name: page_size + description: The maximum number of records to retrieve per page. + type: String + defaultValue: "" + - name: page + description: The page number of the results to retrieve. + type: String + defaultValue: "" + - name: template_ids + description: A comma-separated list of work order template GUIDs. Used as a filtering argument. + type: String + defaultValue: "" + isArray: true + - name: template_name + description: The work order template name. Used as a filtering argument. + type: String + defaultValue: "" + outputs: + - type: String + contextPath: BmcITSM.WorkOrderTemplate.Id + description: The work order template ID. + - type: String + contextPath: BmcITSM.WorkOrderTemplate.Name + description: The work order template name. + - type: String + contextPath: BmcITSM.WorkOrderTemplate.GUID + description: The work order template GUID. + - name: bmc-itsm-work-order-create + description: Creates a new work order ticket. + arguments: + - name: template_guid + description: The instance GUID of the template to use. The GUID can be retrieved by executing the bmc-itsm-work-order-template-list command. + type: String + defaultValue: "" + - name: first_name + description: Requester first name. + type: String + required: false + defaultValue: "" + - name: last_name + description: Requester last name. + type: String + required: false + defaultValue: "" + - name: customer_first_name + description: Customer first name. + type: String + required: true + defaultValue: "" + - name: customer_last_name + description: Customer last name. + type: String + required: true + defaultValue: "" + - name: customer_company + description: Customer company. + type: String + defaultValue: "" + required: true + - name: customer_person_id + description: Customer person ID. Use it when customer first and last name pair is not unique. + type: String + required: false + defaultValue: "" + - name: summary + description: The work order summary. + type: String + required: true + defaultValue: "" + - name: detailed_description + description: The work order ticket detailed description. + type: String + required: true + defaultValue: "" + - name: status + description: The work order status. + required: true + defaultValue: "" + predefined: + - Assigned + - Pending + - Waiting Approval + - Planning + - In Progress + - Completed + - Rejected + - Cancelled + - Closed + auto: PREDEFINED + - name: additional_fields + description: 'The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Example: additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent".' + type: String + defaultValue: "" + - name: priority + description: The work order ticket priority. + required: true + defaultValue: "" + predefined: + - Critical + - High + - Medium + - Low + auto: PREDEFINED + - name: work_order_type + description: The work order ticket type. + defaultValue: "" + predefined: + - General + - Project + auto: PREDEFINED + - name: location_company + description: The company associated with the task process. + type: String + required: true + defaultValue: "" + - name: scedulded_start_date + description: The work order ticket scheduled future start date. For example, in 12 hours, in 7 days. + type: String + defaultValue: "" + - name: scedulded_end_date + description: The work order ticket scheduled future end date. For example, in 12 hours, in 7 days. + type: String + defaultValue: "" + outputs: + - contextPath: BmcITSM.WorkOrder.RequestID + description: The work order ticket unique Request ID. + type: String + - contextPath: BmcITSM.WorkOrder.DisplayID + description: The work order ticket unique Display ID. + type: String + - contextPath: BmcITSM.WorkOrder.CreateDate + description: The work order ticket creation date time in UTC. + type: Date + - name: bmc-itsm-work-order-update + description: Updates the work order ticket. + arguments: + - name: request_id + description: The ID of the work order ticket to update. + type: String + required: true + defaultValue: "" + - name: summary + description: The work order ticket summary. + type: String + - name: detailed_description + description: The work order ticket detailed description. + type: String + defaultValue: "" + - name: priority + description: The work order ticket priority. + defaultValue: "" + predefined: + - Critical + - High + - Medium + - Low + auto: PREDEFINED + - name: status + description: The work order ticket status. + defaultValue: "" + auto: PREDEFINED + predefined: + - Assigned + - Pending + - Waiting Approval + - Planning + - In Progress + - Completed + - Rejected + - Cancelled + - Closed + - name: status_reason + description: The reason for changing the ticket status. + defaultValue: "" + auto: PREDEFINED + predefined: + - Initial Status + - Awaiting Request Assignee + - Client Hold + - Client Additional Information Requested + - Client Action Required + - Support Contact Hold + - Local Site Action Required + - Purchase Order Approval + - Supplier Delivery + - Third Party Vendor Action Required + - Infrastructure Change + - Work not started + - Successful + - Successful with Issues + - Cancelled by Requester + - Cancelled by Support + - Customer Close + - System Close + - System Close with Issues + - name: company + description: The company associated with the requester. By default it is determined by the logged in user. + type: String + defaultValue: "" + - name: location_company + description: The company associated with the work order process. + type: String + defaultValue: "" + - name: assignee + description: The full name of the employee the work order is assigned to. It can be retrieved by using the bmc-itsm-user-list command. + type: String + defaultValue: "" + - name: support_organization + description: The organization for the problem assignee's support organization. It makes up the second tier of the problem assignee's support organization data structure. The arguments support_organization, support_group should be provided together. It can be retrieved by using the bmc-itsm-support-group-list command. + type: String + defaultValue: + - name: support_group + description: The group for the problem assignee's support group. It makes up the third tier of the problem assignee's support organization data structure. The arguments support_organization, support_group should be provided together. It can be retrieved by using the bmc-itsm-support-group-list command. + type: String + defaultValue: "" + - name: work_order_type + description: The work order ticket type. + defaultValue: "" + predefined: + - General + - Project + auto: PREDEFINED + - name: additional_fields + description: 'The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Example: additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent".' + type: String + defaultValue: "" + - name: scedulded_start_date + description: The work order ticket scheduled future start date. For example, in 12 hours, in 7 days. + type: String + defaultValue: "" + - name: scedulded_end_date + description: The work order ticket scheduled future end date. For example, in 12 hours, in 7 days. + type: String + defaultValue: "" + outputs: [] isfetch: true ismappable: true isremotesyncin: true diff --git a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM_description.md b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM_description.md index c09705192371..cb2bc103b8f7 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM_description.md +++ b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM_description.md @@ -7,7 +7,8 @@ - Problem investigation - Known error - Task - - Incident + - Incident + - Work order **Note:** To delete a ticket the user must have an Admin role. diff --git a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM_test.py b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM_test.py index 3a1f8e5ac67b..675c49954956 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM_test.py +++ b/Packs/BmcITSM/Integrations/BmcITSM/BmcITSM_test.py @@ -1181,3 +1181,302 @@ def test_gen_fetch_incidents_query(): custom_query, ) assert query == "'Submit Date' <= \"1657032797\" AND 'Submit Date' >\"1657032797\" AND 'Urgency' = \"4-Low\"" + + +@pytest.mark.parametrize( + "response_file_name,command_arguments,expected_outputs_len,expected_desc", + [ + ( + "list_support_group.json", + { + "limit": "2", + }, + 2, + "APX990000000029", + ), + ( + "list_support_group.json", + { + "page": "2", + "page_size": "1" + }, + 1, + "SGP000000000110", + ), + ( + "list_support_group_filter.json", + { + "limit": "2", + "company": "Apex" + }, + 1, + "APX990000000029", + ), + ], +) +def test_list_support_group_command( + response_file_name, + command_arguments, + expected_outputs_len, + expected_desc, + requests_mock, + mock_client, +): + """ + Scenario: List support groups. + Given: + - User has provided valid credentials. + - User may provided pagination args. + - User may provided filtering arguments. + - User may provided query arguments. + When: + - bmc-itsm-support-group-list command called. + Then: + - Ensure outputs prefix is correct. + - Ensure number of items is correct. + - Validate outputs' fields. + """ + from BmcITSM import support_group_list_command + + mock_response = load_mock_response(response_file_name) + url = f"{BASE_URL}/api/arsys/v1/entry/CTM:Support Group" + requests_mock.get(url=url, json=mock_response) + + result = support_group_list_command(mock_client, command_arguments) + outputs = result.outputs + + assert result.outputs_prefix == "BmcITSM.SupportGroup" + assert len(outputs) == expected_outputs_len + assert outputs[0]["SupportGroupID"] == expected_desc + + +@pytest.mark.parametrize( + "response_file_name,command_arguments,expected_outputs_len,expected_desc", + [ + ( + "list_work_order_template.json", + { + "limit": "2", + }, + 2, + "IDGCWH5RDMNSBARVRM5ERVRM5EKP11", + ), + ( + "list_work_order_template.json", + { + "page": "2", + "page_size": "1" + }, + 1, + "IDGCWH5RDMNSBARVRNNGRVRNNGKY0X", + ), + ( + "list_work_order_template_filter.json", + { + "limit": "2", + "template_name": "UNIX User" + }, + 1, + "IDGCWH5RDMNSBARWFDYBRWFDYBB8NV", + ), + ( + "list_work_order_template.json", + { + "limit": 2, + "template_ids": "IDGCWH5RDMNSBARVRM5ERVRM5EKP11,IDGCWH5RDMNSBARVRNNGRVRNNGKY0X" + }, + 2, + "IDGCWH5RDMNSBARVRM5ERVRM5EKP11" + ), + ( + "list_work_order_template_filter.json", + { + "limit": 2, + "query": "Summary like \"%UNIX%\"" + }, + 1, + "IDGCWH5RDMNSBARWFDYBRWFDYBB8NV" + ), + ], +) +def test_list_work_order_template_command( + response_file_name, + command_arguments, + expected_outputs_len, + expected_desc, + requests_mock, + mock_client, +): + """ + Scenario: List work order templates. + Given: + - User has provided valid credentials. + - User may provided pagination args. + - User may provided filtering arguments. + - User may provided query arguments. + When: + - bmc-itsm-work-order-template-list command called. + Then: + - Ensure outputs prefix is correct. + - Ensure number of items is correct. + - Validate outputs' fields. + """ + from BmcITSM import work_order_template_list_command + + mock_response = load_mock_response(response_file_name) + url = f"{BASE_URL}/api/arsys/v1/entry/WOI:Template" + requests_mock.get(url=url, json=mock_response) + + result = work_order_template_list_command(mock_client, command_arguments) + outputs = result.outputs + + assert result.outputs_prefix == "BmcITSM.WorkOrderTemplate" + assert len(outputs) == expected_outputs_len + assert outputs[0]["GUID"] == expected_desc + + +@pytest.mark.parametrize( + "response_file_name,command_arguments,expected_outputs_len,expected_id", + [ + ( + "create_work_order.json", + { + "customer_first_name": "Scully", + "customer_last_name": "Agent", + "customer_company": "Calbro Services", + "summary": "Sample WO 20240205", + "detailed_description": "Sample WO 20240205", + "status": "Assigned", + "priority": "Low", + "location_company": "Calbro Services", + }, + 3, + "WO0000000000701", + ), + ], +) +def test_work_order_create_command( + response_file_name, + command_arguments, + expected_outputs_len, + expected_id, + requests_mock, + mock_client, +): + """ + Scenario: Create Work order. + Given: + - User has provided valid credentials. + When: + - bmc-itsm-work-order-create command called. + Then: + - Ensure outputs prefix is correct. + - Ensure number of items is correct. + - Validate outputs' fields. + """ + from BmcITSM import work_order_create_command + + mock_response = load_mock_response(response_file_name) + fields = "values(Request ID,WorkOrder_ID,Create Date)" + url = f"{BASE_URL}/api/arsys/v1/entry/WOI:WorkOrderInterface_Create?fields={fields}" + requests_mock.post(url=url, json=mock_response) + + request_id = "WO0000000000701" + url = f"{BASE_URL}/api/arsys/v1/entry/WOI:WorkOrderInterface/{request_id}" + requests_mock.get(url=url, json=load_mock_response("get_work_order.json")) + + result = work_order_create_command(mock_client, command_arguments) + outputs = result.outputs + + assert result.outputs_prefix == "BmcITSM.WorkOrder" + assert len(outputs) == expected_outputs_len + assert outputs["RequestID"] == expected_id + + +@pytest.mark.parametrize( + "request_id,command_arguments,expected_msg", + [ + ( + "WO0000000000701", + { + "request_id": "WO0000000000701", + "status": "In Progress", + "summary": "Updated Summary" + + }, + "Work Order: WO0000000000701 was successfully updated.", + ), + ], +) +def test_work_order_update_command(request_id, command_arguments, expected_msg, + requests_mock, mock_client): + """ + Scenario: Update Work error. + Given: + - User has provided valid credentials. + - User has provided updated values + When: + - bmc-itsm-work-order-update command called. + Then: + - Ensure the human readable message is correct. + """ + from BmcITSM import work_order_update_command + + url = f"{BASE_URL}/api/arsys/v1/entry/WOI:WorkOrder/{request_id}" + requests_mock.put(url=url, text="") + + result = work_order_update_command(mock_client, command_arguments) + readable_output = result.readable_output + + assert readable_output == expected_msg + + +@pytest.mark.parametrize( + "response_file_name,command_arguments,ticket_form,expected_outputs_len,expected_name", + [ + ( + "list_tickets_work_order.json", + { + "limit": "2", + "ticket_ids": "WO0000000000009", + "ticket_type": "work order", + }, + "WOI:WorkOrderInterface", + 1, + "WO0000000000009", + ), + ], +) +def test_ticket_list_work_order_command( + response_file_name, + command_arguments, + ticket_form, + expected_outputs_len, + expected_name, + requests_mock, + mock_client, +): + """ + Scenario: List work order tickets. + Given: + - User has provided valid credentials. + - User may Provided filtering arguments. + When: + - bmc-itsm-ticket-list command called. + Then: + - Ensure outputs prefix is correct. + - Ensure number of items is correct. + - Validate outputs' fields. + """ + from BmcITSM import ticket_list_command + + mock_response = load_mock_response(response_file_name) + url = f"{BASE_URL}/api/arsys/v1/entry/{ticket_form}" + requests_mock.get(url=url, json=mock_response) + + result = ticket_list_command(mock_client, command_arguments) + outputs = result.outputs + + assert result.outputs_prefix == "BmcITSM.Ticket" + assert len(outputs) == expected_outputs_len + assert outputs[0]["DisplayID"] == expected_name diff --git a/Packs/BmcITSM/Integrations/BmcITSM/README.md b/Packs/BmcITSM/Integrations/BmcITSM/README.md index 62e821a541c1..8b42b26fce92 100644 --- a/Packs/BmcITSM/Integrations/BmcITSM/README.md +++ b/Packs/BmcITSM/Integrations/BmcITSM/README.md @@ -1,5 +1,5 @@ -BMC Helix ITSM integration enables customers to manage service request, incident, change request, task, problem investigation and known error tickets. -This integration was integrated and tested with version 21.02 of BmcITSM +BMC Helix ITSM integration enables customers to manage service request, incident, change request, task, problem investigation, known error and work order tickets. +This integration was integrated and tested with version 22.1.05 of BmcITSM ## Configure BMC Helix ITSM on Cortex XSOAR @@ -43,16 +43,16 @@ Retrieves a list of user profiles from BMC Helix ITSM. The records are retrieved | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| user_ids | A comma-separated list of user IDs. Used as a filtering argument. Possible values are: . | Optional | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). Possible values are: . | Optional | -| limit | The maximum number of records to retrieve. Possible values are: . Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. Possible values are: . | Optional | -| page | The page number of the results to retrieve. Possible values are: . | Optional | -| first_name | The user first name. Used as a filtering argument. Possible values are: . | Optional | -| last_name | The user first name. Used as a filtering argument. Possible values are: . | Optional | -| company | The user company name. Used as a filtering argument. Possible values are: . | Optional | -| department | The user department name. Used as a filtering argument. Possible values are: . | Optional | -| organization | The user organization name. Used as a filtering argument. Possible values are: . | Optional | +| user_ids | A comma-separated list of user IDs. Used as a filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| first_name | The user first name. Used as a filtering argument. | Optional | +| last_name | The user first name. Used as a filtering argument. | Optional | +| company | The user company name. Used as a filtering argument. | Optional | +| department | The user department name. Used as a filtering argument. | Optional | +| organization | The user organization name. Used as a filtering argument. | Optional | #### Context Output @@ -119,13 +119,13 @@ Retrieves a list of companies from BMC Helix ITSM. The records are retrieved by | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| company_ids | A comma-separated list of company ID. Filtering argument. Possible values are: . | Optional | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). Possible values are: . | Optional | -| limit | The maximum number of records to retrieve. Possible values are: . Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. Possible values are: . | Optional | -| page | The page number of the results to retrieve. Possible values are: . | Optional | -| company | The user company name. Used as a filtering argument. Possible values are: . | Optional | -| company_type | The user company type. Used as a filtering argument. Possible values are: . | Optional | +| company_ids | A comma-separated list of company ID. Filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| company | The user company name. Used as a filtering argument. | Optional | +| company_type | The user company type. Used as a filtering argument. | Optional | #### Context Output @@ -180,12 +180,12 @@ Retrieves a list of service request definitions. The records are retrieved by th | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| srd_ids | A comma-separated list of service request definition IDs. Used as a filtering argument. Possible values are: . | Optional | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). Possible values are: . | Optional | -| limit | The maximum number of records to retrieve. Possible values are: . Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. Possible values are: . | Optional | -| page | The page number of the results to retrieve. Possible values are: . | Optional | -| description | The service request ticket definition description. Used as a filtering argument. Possible values are: . | Optional | +| srd_ids | A comma-separated list of service request definition IDs. Used as a filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| description | The service request ticket definition description. Used as a filtering argument. | Optional | #### Context Output @@ -240,19 +240,19 @@ Retrieves a list of BMC Helix ITSM tickets. The records are retrieved by the que | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_type | The type of tickets to search for. Possible values are: service request, incident, task, change request, problem investigation, known error. | Required | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). Possible values are: . | Optional | -| limit | The maximum number of records to retrieve. Possible values are: . Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. Possible values are: . | Optional | -| page | The page number of the results to retrieve. Possible values are: . | Optional | -| ticket_ids | A comma-separated list of ticket request IDs. Used as a filtering argument. Possible values are: . | Optional | +| ticket_type | The type of tickets to search for. Possible values are: service request, incident, task, change request, problem investigation, known error, work order. | Required | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| ticket_ids | A comma-separated list of ticket request IDs. Used as a filtering argument. Use Display ID for work order type. | Optional | | status | The status of the tickets to fetch. Since each ticket type has its own unique set of statuses, select only statuses that match the selected ticket type(s). Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed, New, Assigned, Resolved, Request For Authorization, Request For Change, Planning In Progress, Scheduled For Review, Scheduled For Approval, Scheduled, Implementation In Progress, Staged, Work In Progress, Waiting, Bypassed, Under Review, Under Investigation, Scheduled For Correction, Assigned To Vendor, No Action Planned, Corrected. | Optional | | impact | The ticket impact. Used as a filtering argument. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | | urgency | The ticket urgency. Used as a filtering argument. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | | priority | The ticket priority. Used as a filtering argument. Possible values are: Critical, High, Medium, Low. | Optional | | risk_level | The ticket risk level. Used as a filtering argument. Possible values are: Risk Level 1, Risk Level 2, Risk Level 3, Risk Level 4. | Optional | | change_type | The ticket change type level. Relevant only for ticket type change requests. Used as a filtering argument. Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | -| summary | The ticket summary. Used as a filtering argument. Possible values are: . | Optional | +| summary | The ticket summary. Used as a filtering argument. | Optional | #### Context Output @@ -387,7 +387,7 @@ Retrieves a list of BMC Helix ITSM tickets. The records are retrieved by the que ### bmc-itsm-service-request-create *** -Creates a new service request ticket. A service request ticket is the request record that is generated from the service request definition to manage and track the execution. To create it, you need to provide the srd_instance_id argument, which can be retrieved by by executing the bmc-itsm-service-request-definition-list command and extracting the instanceID field. User and company arguments can be retrieved by executing the bmc-itsm-user-list and bmc-itsm-company-list. +Creates a new service request ticket. A service request ticket is the request record that is generated from the service request definition to manage and track the execution. To create it, you need to provide the srd_instance_id argument, which can be retrieved by by executing the bmc-itsm-service-request-definition-list command and extracting the instanceID field. User and company arguments can be retrieved by executing the bmc-itsm-user-list and bmc-itsm-company-list. To see the entire JSON, you can use the raw_response=true at the end of the command. #### Base Command @@ -397,15 +397,15 @@ Creates a new service request ticket. A service request ticket is the request re | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| srd_instance_id | The instance ID of the service request ticket. It can be retrieved by executing bmc-itsm-service-request-definition-list command. . Possible values are: . | Required | -| first_name | The requester first name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. Possible values are: . | Optional | -| last_name | The requester last name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. . Possible values are: . | Optional | -| login_id | The requester login ID. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. Possible values are: . | Optional | -| summary | The service request ticket summary. Possible values are: . | Optional | -| status | The service request ticket status. . Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | +| srd_instance_id | The instance ID of the service request ticket. It can be retrieved by executing bmc-itsm-service-request-definition-list command. | Required | +| first_name | The requester first name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. | Optional | +| last_name | The requester last name. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. | Optional | +| login_id | The requester login ID. By default it is determined by the logged in user. If provided, login_id, first_name, and last_name arguments must be provided together. | Optional | +| summary | The service request ticket summary. | Optional | +| status | The service request ticket status. Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | | urgency | The ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | | impact | The ticket impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: . | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | #### Context Output @@ -449,19 +449,19 @@ Updates the details of a service request ticket for a given request ID. User and | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The unique identifier of the service request ticket to update. Possible values are: . | Required | -| customer_first_name | The customer first name. By default it is determined by the logged in user. . Possible values are: . | Optional | -| customer_last_name | The customer last name. By default it is determined by the logged in user. . Possible values are: . | Optional | -| status | The service request ticket status. . Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | +| ticket_request_id | The unique identifier of the service request ticket to update. | Required | +| customer_first_name | The customer first name. By default it is determined by the logged in user. | Optional | +| customer_last_name | The customer last name. By default it is determined by the logged in user. | Optional | +| status | The service request ticket status. Possible values are: Draft, In Cart, In Review, Submitted, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | | urgency | The ticket request urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | | impact | Incident Request impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | -| status_reason | The reason for updating the status. Required only if status argument is provided. . Possible values are: Review, Need More Information, Approval, System Error, With Issues, Automatically Closed, Successful, By User, By Provider, System, Cancelled, Reopen By User. | Optional | -| location_company | The company associated with the service request process. Possible values are: . | Optional | -| region | The region associated with the company location. Possible values are: . | Optional | -| site_group | The site group associated with the region. Possible values are: . | Optional | -| site | The site associated with the site group. Possible values are: . | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: . | Optional | +| status_reason | The reason for updating the status. Required only if status argument is provided. Possible values are: Review, Need More Information, Approval, System Error, With Issues, Automatically Closed, Successful, By User, By Provider, System, Cancelled, Reopen By User. | Optional | +| location_company | The company associated with the service request process. | Optional | +| region | The region associated with the company location. | Optional | +| site_group | The site group associated with the region. | Optional | +| site | The site associated with the site group. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | #### Context Output @@ -485,26 +485,26 @@ Update incident ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The ID of the incident ticket to update. Possible values are: . | Required | -| first_name | The customer first name the incident ticket is for. Possible values are: . | Optional | -| last_name | The customer last name the incident ticket is for. Possible values are: . | Optional | -| summary | The incident ticket summary. Possible values are: . | Optional | -| service_type | The type of the incident ticket. . Possible values are: User Service Restoration, User Service Request, Infrastructure Restoration, Infrastructure Event, Security Incident. | Optional | +| ticket_request_id | The ID of the incident ticket to update. | Required | +| first_name | The customer first name the incident ticket is for. | Optional | +| last_name | The customer last name the incident ticket is for. | Optional | +| summary | The incident ticket summary. | Optional | +| service_type | The type of the incident ticket. Possible values are: User Service Restoration, User Service Request, Infrastructure Restoration, Infrastructure Event, Security Incident. | Optional | | urgency | The ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | | impact | The ticket impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | | status | The incident ticket status. Possible values are: New, Assigned, In Progress, Pending, Resolved, Closed, Cancelled. | Optional | -| reported_source | The incident ticket reported source. . Possible values are: Direct Input, Email,External Escalation, Fax, Self Service, Systems Management, Phone, Voice Mail, Walk In, Web, Other, BMC Impact Manager Event. | Optional | +| reported_source | The incident ticket reported source. Possible values are: Direct Input, Email,External Escalation, Fax, Self Service, Systems Management, Phone, Voice Mail, Walk In, Web, Other, BMC Impact Manager Event. | Optional | | additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assigned Group, Assignee, or any other custom field.. | Optional | -| detailed_description | The incident ticket summary. Possible values are: . | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. Possible values are: . | Optional | -| assigned_support_company | The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. Possible values are: . | Optional | -| assigned_support_organization | The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. Possible values are: . | Optional | -| assigned_group | The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. Possible values are: . | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| assignee_login_id | The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. Possible values are: . | Optional | -| region | The region, which makes up the second tier of the customer’s business organization data structure. Possible values are: . | Optional | -| site_group | The site group associated with the region. Possible values are: . | Optional | -| site | The site associated with the site group. Possible values are: . | Optional | +| detailed_description | The incident ticket summary. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| assigned_support_company | The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. | Optional | +| assigned_support_organization | The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. | Optional | +| assigned_group | The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assignee_login_id | The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. | Optional | +| region | The region, which makes up the second tier of the customer’s business organization data structure. | Optional | +| site_group | The site group associated with the region. | Optional | +| site | The site associated with the site group. | Optional | | status_reason | The reason for updating the ticket status. Required when status is provided. Possible values are: Infrastructure Change Created, Local Site Action Required, Purchase Order Approval, Registration Approval, Supplier Delivery, Support Contact Hold, Third Party Vendor Action Reqd, Client Action Required, Infrastructure Change Request, Future Enhancement, Pending Original Incident, Client Hold, Monitoring Incident, Customer Follow-Up Required, Temporary Corrective Action, No Further Action Required, Resolved by Original Incident, Automated Resolution Reported, No longer a Causal CI, Pending Causal Incident Resolution, Resolved by Causal Incident. | Optional | | resolution | The ticket resolution description. Required when status is provided. | Optional | @@ -530,8 +530,8 @@ Deletes a ticket by its request ID. Only admin users can perform this command. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_ids | A comma-separated list of ticket request IDs to delete. Possible values are: . | Required | -| ticket_type | The type of the tickets to delete. Possible values are: incident, task, change request, problem investigation, known error. | Required | +| ticket_ids | A comma-separated list of ticket request IDs to delete. | Required | +| ticket_type | The type of the tickets to delete. Possible values are: incident, task, change request, problem investigation, known error, work order. | Required | #### Context Output @@ -555,26 +555,26 @@ Creates a new incident ticket. An incident is any event that is not part of the | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| first_name | The customer first name the incident ticket is for. Possible values are: . | Required | -| last_name | The customer last name the incident ticket is for. Possible values are: . | Required | -| template_instance_id | The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The instance ID can be retrieved by executing the bmc-itsm-incident-template-list command. Possible values are: . | Optional | -| summary | The incident ticket summary. Required when the template_instance_id argument is not provided. Possible values are: . | Optional | +| first_name | The customer first name the incident ticket is for. | Required | +| last_name | The customer last name the incident ticket is for. | Required | +| template_instance_id | The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The instance ID can be retrieved by executing the bmc-itsm-incident-template-list command. | Optional | +| summary | The incident ticket summary. Required when the template_instance_id argument is not provided. | Optional | | service_type | The type of the incident ticket. Required when the template_instance_id argument is not provided. Possible values are: User Service Restoration, User Service Request, Infrastructure Restoration, Infrastructure Event, Security Incident. | Optional | | urgency | The ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Required | | impact | The ticket impact. Required when the creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Required | | status | Incident status. Possible values are: New, Assigned, In Progress, Pending, Resolved, Closed, Cancelled. | Required | | reported_source | The incident ticket reported source. Required when the template_instance_id argument is not provided. Possible values are: Direct Input, Email,External Escalation, Fax, Self Service, Systems Management, Phone, Voice Mail, Walk In, Web, Other, BMC Impact Manager Event. | Optional | | additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assigned Group, Assignee, or any other custom field.. | Optional | -| details | The incident ticket detailed description. Possible values are: . | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. Possible values are: . | Optional | -| assigned_support_company | The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. Possible values are: . | Optional | -| assigned_support_organization | The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. Possible values are: . | Optional | -| assigned_group | The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. Possible values are: . | Optional | -| assignee | The full name of the employee the ticket will be assigned to. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| assignee_login_id | The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| region | The region associated with the company. Possible values are: . | Optional | -| site_group | The site group associated with the region. Possible values are: . | Optional | -| site | The site associated with the site group. Possible values are: . | Optional | +| details | The incident ticket detailed description. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| assigned_support_company | The company for the assignee’s support organization. It makes up the first tier of the assignee’s support organization data structure. | Optional | +| assigned_support_organization | The organization for the assignee’s support organization. It makes up the second tier of the assignee’s support organization data structure. | Optional | +| assigned_group | The group for the assignee’s support organization. It makes up the third tier of the assignee’s support organization data structure. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assignee_login_id | The login ID of the assignee. The assignee and assignee_login_id arguments must be provided together. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| region | The region associated with the company. | Optional | +| site_group | The site group associated with the region. | Optional | +| site | The site associated with the site group. | Optional | #### Context Output @@ -620,20 +620,20 @@ Creates a change request ticket in BMC Helix ITSM. The ticket is created by usin | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| first_name | The requester first name. Possible values are: . | Required | -| last_name | The requester last name. Possible values are: . | Required | -| customer_first_name | The customer first name. . Possible values are: . | Optional | -| customer_last_name | The customer last name. Possible values are: . | Optional | -| summary | The change request ticket title. Required when the template ID argument is not provided. Possible values are: . | Optional | -| template_id | The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The ID can be retrieved by executing the bmc-itsm-change-request-template-list command. Possible values are: . | Optional | +| first_name | The requester first name. | Required | +| last_name | The requester last name. | Required | +| customer_first_name | The customer first name. | Optional | +| customer_last_name | The customer last name. | Optional | +| summary | The change request ticket title. Required when the template ID argument is not provided. | Optional | +| template_id | The instance ID of the template to use. Required only when the ticket attributes should be based on the template's fields. The ID can be retrieved by executing the bmc-itsm-change-request-template-list command. | Optional | | change_type | The change request ticket type. Required when the ticket creation is without a template. Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | | change_timing | The class of the change request ticket which best describes your scenario. Possible values are: Emergency, Expedited, Latent, Normal, No Impact, Standard. | Optional | | impact | The change request ticket impact. Required when the ticket creation is without a template. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | | urgency | The change request ticket urgency. Required when the ticket creation is without a template. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | | risk_level | The change request ticket risk level. Required when the ticket creation is without a template. Possible values are: Risk Level 1, Risk Level 2, Risk Level 3, Risk Level 4, Risk Level 5. | Optional | | status | The change request ticket status. Required when the ticket creation is without a template. Possible values are: Request For Authorization, Request For Change, Planning In Progress, Scheduled For Review, Scheduled For Approval, Scheduled, Implementation In Progress, Pending, Rejected, Completed, Closed, Cancelled. | Optional | -| location_company | The company associated with the change request process. Required when template ID argument is not provided. Possible values are: . | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: . | Optional | +| location_company | The company associated with the change request process. Required when template ID argument is not provided. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | #### Context Output @@ -680,27 +680,27 @@ Updates the details of change request ticket for the specified request ID. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | | ticket_request_id | The ID of the change request ticket to update. | Required | -| first_name | The customer first name the change request ticket is for. . Possible values are: . | Optional | -| last_name | The customer last name the change request ticket is for. . Possible values are: . | Optional | -| summary | The change request ticket summary. Possible values are: . | Optional | -| change_type | The change request ticket type. . Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | +| first_name | The customer first name the change request ticket is for. | Optional | +| last_name | The customer last name the change request ticket is for. | Optional | +| summary | The change request ticket summary. | Optional | +| change_type | The change request ticket type. Possible values are: Project, Change, Release, Asset Configuration, Asset Management, Asset Lease, Purchase Requisition, Asset Maintenance. | Optional | | change_timing | The class of the change request ticket which best describes your scenario. Possible values are: Emergency, Expedited, Latent, Normal, No Impact, Standard. | Optional | | impact | The change request ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | | urgency | The change request ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | | risk_level | The change request ticket risk level. Possible values are: Risk Level 1, Risk Level 2, Risk Level 3, Risk Level 4, Risk Level 5. | Optional | | status | The change request ticket status. Possible values are: Request For Authorization, Request For Change, Planning In Progress, Scheduled For Review, Scheduled For Approval, Scheduled, Implementation In Progress, Pending, Rejected, Completed, Closed, Cancelled. | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. Possible values are: . | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. Possible values are: . | Optional | -| organization | The organization associated with the requester. Possible values are: . | Optional | -| department | The department associated with the requester. Possible values are: . | Optional | -| location_company | The company associated with the change request process. Possible values are: . | Optional | -| region | The region associated with the company location. Possible values are: . | Optional | -| site_group | The site group associated with the region. Possible values are: . | Optional | -| site | The site associated with the site group. Possible values are: . | Optional | -| support_organization | The second tier of the change manager’s support organization data structure. Possible values are: . | Optional | -| support_group_name | The third tier of the change manager’s support organization data structure. Possible values are: . | Optional | -| status_reason | The reason for updating the ticket status. Required when status is provided. . Possible values are: No Longer Required, Funding Not Available, To Be Re-Scheduled, Resources Not Available, Successful, Successful with Issues, Unsuccessful, Backed Out, Final Review Complete, Final Review Required, Additional Coding Required, Insufficient Task Data, In Verification, In Rollout, Insufficient Change Data, Schedule Conflicts, In Development, In Test, In Build, In Rollback, In Documentation, Vendor Purchase, Support Group Communication, Task Review, Miscellaneous, Future Enhancement, Manager Intervention, Accepted, Assigned, Built, On Hold. | Optional | -| details | The change request ticket details. Possible values are: . | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee, or any other custom field. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| organization | The organization associated with the requester. | Optional | +| department | The department associated with the requester. | Optional | +| location_company | The company associated with the change request process. | Optional | +| region | The region associated with the company location. | Optional | +| site_group | The site group associated with the region. | Optional | +| site | The site associated with the site group. | Optional | +| support_organization | The second tier of the change manager’s support organization data structure. | Optional | +| support_group_name | The third tier of the change manager’s support organization data structure. | Optional | +| status_reason | The reason for updating the ticket status. Required when status is provided. Possible values are: No Longer Required, Funding Not Available, To Be Re-Scheduled, Resources Not Available, Successful, Successful with Issues, Unsuccessful, Backed Out, Final Review Complete, Final Review Required, Additional Coding Required, Insufficient Task Data, In Verification, In Rollout, Insufficient Change Data, Schedule Conflicts, In Development, In Test, In Build, In Rollback, In Documentation, Vendor Purchase, Support Group Communication, Task Review, Miscellaneous, Future Enhancement, Manager Intervention, Accepted, Assigned, Built, On Hold. | Optional | +| details | The change request ticket details. | Optional | #### Context Output @@ -713,7 +713,7 @@ There is no context output for this command. >Incident: CRQ000000000313 was successfully updated. ### bmc-itsm-task-create *** -Creates a new task ticket. By splitting cases into individual tasks (assignments), you can focus on one assignment at a time to resolve cases more efficiently. Task ticket type can be attached only to the following ticket types: change request, incident, problem investigation, and known error. +Creates a new task ticket. By splitting cases into individual tasks (assignments), you can focus on one assignment at a time to resolve cases more efficiently. Task ticket type can be attached only to the following ticket types: change request, incident, problem investigation, known error and work order. #### Base Command @@ -723,26 +723,26 @@ Creates a new task ticket. By splitting cases into individual tasks (assignments | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| template_id | The instance ID of the template to use. The ID can be retrieved by executing the bmc-itsm-task-template-list command. Possible values are: . | Optional | -| summary | The task ticket summary. Possible values are: . | Required | -| details | The task ticket detailed description. Possible values are: . | Required | -| root_ticket_type | The parent ticket type. Possible values are: change request, incident, problem investigation, known error. | Required | -| root_request_id | The request ID of the parent ticket. Can be found in the context output of the bmc-itsm-ticket-list command. . Possible values are: . | Required | -| root_request_name | The display name of the parent ticket in the task ticket. If not provided, the parent ticket displayID is displayed. . Possible values are: . | Optional | -| root_request_mode | The parent ticket request mode. . Possible values are: Real, Simulation. Default is Real. | Optional | +| template_id | The instance ID of the template to use. The ID can be retrieved by executing the bmc-itsm-task-template-list command. | Optional | +| summary | The task ticket summary. | Required | +| details | The task ticket detailed description. | Required | +| root_ticket_type | The parent ticket type. Possible values are: change request, incident, problem investigation, known error, work order. | Required | +| root_request_id | The request ID of the parent ticket. Can be found in the context output of the bmc-itsm-ticket-list command. Use Display ID for work orders. | Required | +| root_request_name | The display name of the parent ticket in the task ticket. If not provided, the parent ticket displayID is displayed. | Optional | +| root_request_mode | The parent ticket request mode. Possible values are: Real, Simulation. Default is Real. | Optional | | status | The task status. Possible values are: Staged, Assigned, Pending, Work In Progress, Waiting, Closed, Bypassed. | Required | | task_type | Whether the task is manual or automatic. Possible values are: Automatic, Manual. | Optional | | additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assignee or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assignee or any other custom field.. | Optional | | priority | The task ticket priority. Possible values are: Critical, High, Medium, Low. | Required | -| location_company | The company associated with the task process. Possible values are: . | Required | -| support_company | The technical support team associated with the company. Possible values are: . | Optional | -| assigned_support_organization | The organization for the task's support organization. It makes up the second tier of the task’s support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. Possible values are: . | Optional | -| assigned_support_group | The group for the task's support organization. It makes up the third tier of the task's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. Possible values are: . | Optional | +| location_company | The company associated with the task process. | Required | +| support_company | The technical support team associated with the company. | Optional | +| assigned_support_organization | The organization for the task's support organization. It makes up the second tier of the task’s support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | +| assigned_support_group | The group for the task's support organization. It makes up the third tier of the task's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | | impact | The task ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | | urgency | The task ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| scedulded_start_date | The task ticket scheduled future start date. For example, in 12 hours, in 7 days. Possible values are: . | Optional | -| scedulded_end_date | The task ticket scheduled future end date. For example, in 12 hours, in 7 days. Possible values are: . | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| scedulded_start_date | The task ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | +| scedulded_end_date | The task ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | #### Context Output @@ -788,22 +788,22 @@ Updates the task ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The ID of the task ticket to update. Possible values are: . | Required | -| summary | The task ticket summary. Possible values are: . | Optional | -| details | The task ticket detailed description. Possible values are: . | Optional | +| ticket_request_id | The ID of the task ticket to update. | Required | +| summary | The task ticket summary. | Optional | +| details | The task ticket detailed description. | Optional | | priority | The task ticket priority. Possible values are: Critical, High, Medium, Low. | Optional | | status | The task ticket status. Possible values are: Staged, Assigned, Pending, Work In Progress, Waiting, Closed, Bypassed. | Optional | -| status_reason | The reason for changing the ticket status. Required when the status is changed. . Possible values are: Success, Failed, Cancelled, Assignment, Staging in Progress, Staging Complete, Acknowledgment, Another Task, Task Rule, Completion, Error. | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. Possible values are: . | Optional | -| location_company | The company associated with the task process. Possible values are: . | Optional | -| support_company | The technical support team associated with the company. Possible values are: . | Optional | -| assignee | The full name of the employee the ticket is assigned to. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. Possible values are: . | Optional | -| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. Possible values are: . | Optional | -| task_type | The task ticket type. . Possible values are: Automatic, Manual. | Optional | +| status_reason | The reason for changing the ticket status. Required when the status is changed. Possible values are: Success, Failed, Cancelled, Assignment, Staging in Progress, Staging Complete, Acknowledgment, Another Task, Task Rule, Completion, Error. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| location_company | The company associated with the task process. | Optional | +| support_company | The technical support team associated with the company. | Optional | +| assignee | The full name of the employee the ticket is assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | +| task_type | The task ticket type. Possible values are: Automatic, Manual. | Optional | | additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assignee or any other custom field. Possible values are: The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value".Possible fields: Assignee or any other custom field.. | Optional | -| scedulded_start_date | The task ticket scheduled future start date. For example, in 12 hours, in 7 days. Possible values are: . | Optional | -| scedulded_end_date | The task ticket scheduled future end date. For example, in 12 hours, in 7 days. Possible values are: . | Optional | +| scedulded_start_date | The task ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | +| scedulded_end_date | The task ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | #### Context Output @@ -827,31 +827,31 @@ Creates a problem investigation ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| first_name | The customer first name the ticket request is for. Possible values are: . | Required | -| last_name | The customer last name the ticket request is for. Possible values are: . | Required | +| first_name | The customer first name the ticket request is for. | Required | +| last_name | The customer last name the ticket request is for. | Required | | status | The problem investigation ticket status. Possible values are: Draft, Under Review, Request for Authorization, Assigned, Under Investigation, Pending, Completed, Rejected, Closed, Cancelled. | Required | -| investigation_driver | The problem investigation ticket driver. . Possible values are: High Impact Incident, Re-Occurring Incidents, Non-Routine Incident, Other. | Required | -| summary | The problem investigation ticket summary. Possible values are: . | Required | -| details | The detailed description on the problem investigation ticket. Possible values are: . | Optional | +| investigation_driver | The problem investigation ticket driver. Possible values are: High Impact Incident, Re-Occurring Incidents, Non-Routine Incident, Other. | Required | +| summary | The problem investigation ticket summary. | Required | +| details | The detailed description on the problem investigation ticket. | Optional | | impact | The problem investigation ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Required | | urgency | The problem investigation ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Required | -| target_resolution_date | The future resolution date. For example, in 12 hours, in 7 days. Possible values are: . | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. Possible values are: . | Optional | -| region | The region of the problem investigation location. The arguments region, site_group, and site should be provided together. Possible values are: . | Optional | -| site_group | The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. Possible values are: . | Optional | -| site | The site of the problem investigation location. The arguments region, site_group, and site should be provided together. Possible values are: . | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| assignee_pbm_mgr | The full name of the employee the ticket will be assigned to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| assigned_group_pbm_mgr | The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. Possible values are: . | Optional | -| support_company_pbm_mgr | The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. Possible values are: . | Optional | -| support_organization_pbm_mgr | The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. Possible values are: . | Optional | -| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. Possible values are: . | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. Possible values are: . | Optional | -| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. Possible values are: . | Optional | -| investigation_justification | The justification for the ticket creation. Possible values are: . | Optional | -| temporary_workaround | The problem workaround. Possible values are: . | Optional | -| resolution | The ticket resolution. Possible values are: . | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. Possible values are: . | Optional | +| target_resolution_date | The future resolution date. For example, in 12 hours, in 7 days. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| region | The region of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| site_group | The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| site | The site of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assignee_pbm_mgr | The full name of the employee the ticket will be assigned to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assigned_group_pbm_mgr | The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| support_company_pbm_mgr | The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| support_organization_pbm_mgr | The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | +| investigation_justification | The justification for the ticket creation. | Optional | +| temporary_workaround | The problem workaround. | Optional | +| resolution | The ticket resolution. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. | Optional | #### Context Output @@ -897,28 +897,28 @@ Updates The problem investigation ticket type. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The problem investigation ticket request ID. Possible values are: . | Required | +| ticket_request_id | The problem investigation ticket request ID. | Required | | status | The problem investigation ticket status. Possible values are: Draft, Under Review, Request for Authorization, Assigned, Under Investigation, Pending, Completed, Rejected, Closed, Cancelled. | Optional | -| investigation_driver | The problem investigation ticket driver. . Possible values are: High Impact Incident, Re-Occuring Incidents, Non-Routine Incident, Other. | Optional | -| summary | The problem investigation ticket summary. Possible values are: . | Optional | +| investigation_driver | The problem investigation ticket driver. Possible values are: High Impact Incident, Re-Occuring Incidents, Non-Routine Incident, Other. | Optional | +| summary | The problem investigation ticket summary. | Optional | | impact | The problem investigation ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | | urgency | The problem investigation ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| target_resolution_date | The problem investigation ticket target resolution date. For example, in 12 hours, in 7 days. Possible values are: . | Optional | -| details | The problem investigation ticket detailed description. Possible values are: . | Optional | -| company | The company associated with the requester. By default it is determined by the logged in user. Possible values are: . | Optional | -| region | The region of the problem investigation location. The arguments region, site_group, and site should be provided together. Possible values are: . | Optional | -| site_group | The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. Possible values are: . | Optional | -| site | The site of the problem investigation location.The arguments region, site_group, and site should be provided together. Possible values are: . | Optional | -| assigned_to | The technical support person the ticket is assigned to. Possible values are: . | Optional | -| assigned_group_pbm_mgr | The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. Possible values are: . | Optional | -| support_company_pbm_mgr | The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. Possible values are: . | Optional | -| support_organization_pbm_mgr | The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. Possible values are: . | Optional | -| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. Possible values are: . | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. Possible values are: . | Optional | -| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. Possible values are: . | Optional | -| investigation_justification | The justification for the ticket creation. Possible values are: . | Optional | -| temporary_workaround | The problem workaround. Possible values are: . | Optional | -| resolution | The ticket resolution. Possible values are: . | Optional | +| target_resolution_date | The problem investigation ticket target resolution date. For example, in 12 hours, in 7 days. | Optional | +| details | The problem investigation ticket detailed description. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| region | The region of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| site_group | The site group of the problem investigation location. The arguments region, site_group, and site should be provided together. | Optional | +| site | The site of the problem investigation location.The arguments region, site_group, and site should be provided together. | Optional | +| assigned_to | The technical support person the ticket is assigned to. | Optional | +| assigned_group_pbm_mgr | The group for the problem coordinator’s support organization, which makes up the third tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| support_company_pbm_mgr | The company for the problem coordinator’s support organization, which makes up the first tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| support_organization_pbm_mgr | The organization for the problem coordinator’s support organization, which makes up the second tier of the problem coordinator’s support organization data structure. The arguments support_organization_pbm_mgr, assigned_group_pbm_mgr, and support_company_pbm_mgr should be provided together. | Optional | +| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. The arguments assigned_support_organization, assigned_group, and assigned_support_company should be provided together. | Optional | +| assigned_group | The group for the problem assignee's support organization. It makes up the third tier of the problem assignee's support organization data structure. The arguments assigned_support_organization, assigned_group, and support_company should be provided together. | Optional | +| investigation_justification | The justification for the ticket creation. | Optional | +| temporary_workaround | The problem workaround. | Optional | +| resolution | The ticket resolution. | Optional | | status_reason | The reason for changing the status. Required when the status argument is provided. Possible values are: Publish, Reject, Not Applicable. | Optional | @@ -944,25 +944,25 @@ Create known error ticket. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | | status | The known error ticket status. Possible values are: Assigned, Scheduled For Correction, Assigned To Vendor, No Action Planned, Corrected, Closed, Cancelled. | Required | -| summary | The known error ticket summary. Possible values are: . | Required | -| details | The known error ticket Detailed description. Possible values are: . | Required | +| summary | The known error ticket summary. | Required | +| details | The known error ticket Detailed description. | Required | | impact | The known error ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Required | | urgency | The known error ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Required | | view_access | Whether if the ticket is for internal view or public view. Possible values are: Public, Internal. | Required | -| company | Company associated with the Requester. Possible values are: . | Required | -| target_resolution_date | Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. Possible values are: . | Required | -| resolution | Ticket resolution. Possible values are: . | Optional | -| assigned_group_pbm_mgr | It makes up the third tier of the Problem Coordinator’s Support Organization data structure. Possible values are: . | Optional | -| support_company_pbm_mgr | the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it. . Possible values are: . | Optional | -| support_organization_pbm_mgr | It makes up the second tier of the Problem Coordinator’s Support Organization data structure. Possible values are: . | Optional | -| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. Possible values are: . | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. Possible values are: . | Optional | -| assigned_group | The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. Possible values are: . | Optional | -| investigation_justification | The justification for the ticket creation. Possible values are: . | Optional | -| assignee | The full name of the staff member to whom the ticket will be assigned to. It can be retrieved by using the 'bmc-itsm-user-list' command. Possible values are: . | Optional | -| assignee_pbm_mgr | The full name of the staff member to whom the ticket will be assign to as the problem coordinator. It can be retrieved by using the 'bmc-itsm-user-list' command. Possible values are: . | Optional | -| temporary_workaround | Error workaround. Possible values are: . | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. Possible values are: . | Optional | +| company | Company associated with the Requester. | Required | +| target_resolution_date | Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. | Required | +| resolution | Ticket resolution. | Optional | +| assigned_group_pbm_mgr | It makes up the third tier of the Problem Coordinator’s Support Organization data structure. | Optional | +| support_company_pbm_mgr | the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it. | Optional | +| support_organization_pbm_mgr | It makes up the second tier of the Problem Coordinator’s Support Organization data structure. | Optional | +| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. | Optional | +| assigned_group | The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. | Optional | +| investigation_justification | The justification for the ticket creation. | Optional | +| assignee | The full name of the staff member to whom the ticket will be assigned to. It can be retrieved by using the 'bmc-itsm-user-list' command. | Optional | +| assignee_pbm_mgr | The full name of the staff member to whom the ticket will be assign to as the problem coordinator. It can be retrieved by using the 'bmc-itsm-user-list' command. | Optional | +| temporary_workaround | Error workaround. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. | Optional | #### Context Output @@ -1008,27 +1008,27 @@ Update Known Error ticket type. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| ticket_request_id | The known error ticket request ID. Possible values are: . | Required | +| ticket_request_id | The known error ticket request ID. | Required | | status | The known error ticket status. Possible values are: Assigned, Scheduled For Correction, Assigned To Vendor, No Action Planned, Corrected, Closed, Cancelled. | Optional | -| summary | The known error ticket summary. Possible values are: . | Optional | -| details | The known error ticket detailed description. Possible values are: . | Optional | +| summary | The known error ticket summary. | Optional | +| details | The known error ticket detailed description. | Optional | | impact | The known error ticket impact. Possible values are: 1-Extensive/Widespread, 2-Significant/Large, 3-Moderate/Limited, 4-Minor/Localized. | Optional | | urgency | The known error ticket urgency. Possible values are: 1-Critical, 2-High, 3-Medium, 4-Low. | Optional | -| view_access | The known error ticket internal access. . Possible values are: Public, Internal. | Optional | -| company | Company associated with the Requester. By default is determined by the logged in user. Possible values are: . | Optional | -| target_resolution_date | Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. Possible values are: . | Optional | -| resolution | Ticket resolution. Possible values are: . | Optional | -| assigned_group_pbm_mgr | It makes up the third tier of the Problem Coordinator’s Support Organization data structure. Possible values are: . | Optional | -| support_company_pbm_mgr | the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it. . Possible values are: . | Optional | -| support_organization_pbm_mgr | It makes up the second tier of the Problem Coordinator’s Support Organization data structure. Possible values are: . | Optional | -| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. Possible values are: . | Optional | -| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. Possible values are: . | Optional | -| assigned_group | The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. Possible values are: . | Optional | -| temporary_workaround | Error workaround. Possible values are: . | Optional | -| status_reason | The reason for changing the status. Required when the status is provided. . Possible values are: Duplicate, No Longer Applicable, Pending PIR, Funding Not Available, Pending Infrastructure Change, Pending Third Party Vendor. | Optional | -| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| assignee_pbm_mgr | The full name of the employee the ticket will be assign to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. Possible values are: . | Optional | -| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. Possible values are: . | Optional | +| view_access | The known error ticket internal access. Possible values are: Public, Internal. | Optional | +| company | Company associated with the Requester. By default is determined by the logged in user. | Optional | +| target_resolution_date | Known error resolution date. Future resolution date. For example, in 12 hours, in 7 days. | Optional | +| resolution | Ticket resolution. | Optional | +| assigned_group_pbm_mgr | It makes up the third tier of the Problem Coordinator’s Support Organization data structure. | Optional | +| support_company_pbm_mgr | the Company for the Problem Coordinator’s Support Organization. It makes up the first tier of it. | Optional | +| support_organization_pbm_mgr | It makes up the second tier of the Problem Coordinator’s Support Organization data structure. | Optional | +| assigned_support_company | The company for the problem assignee’s support organization. It makes up the first tier of the problem assignee’s support organization data structure. | Optional | +| assigned_support_organization | The organization for the problem assignee’s support organization. It makes up the second tier of the problem assignee’s support organization data structure. | Optional | +| assigned_group | The group for the problem assignee’s support organization. It makes up the third tier of the problem assignee’s support organization data structure. | Optional | +| temporary_workaround | Error workaround. | Optional | +| status_reason | The reason for changing the status. Required when the status is provided. Possible values are: Duplicate, No Longer Applicable, Pending PIR, Funding Not Available, Pending Infrastructure Change, Pending Third Party Vendor. | Optional | +| assignee | The full name of the employee the ticket will be assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| assignee_pbm_mgr | The full name of the employee the ticket will be assign to as the problem coordinator. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Possible fields: Assigned Group, Assignee or any other custom field. | Optional | #### Context Output @@ -1052,12 +1052,12 @@ Lists all change requests ticket templates. Useful for creating change request t | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| template_ids | A comma-separated list of change request template IDs. Used as a filtering argument. Possible values are: . | Optional | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). Possible values are: . | Optional | -| limit | The maximum number of records to retrieve. Possible values are: . Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. Possible values are: . | Optional | -| page | The page number of the results to retrieve. Possible values are: . | Optional | -| description | The change request ticket description. Used as a filtering argument. Possible values are: . | Optional | +| template_ids | A comma-separated list of change request template IDs. Used as a filtering argument. | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| description | The change request ticket description. Used as a filtering argument. | Optional | #### Context Output @@ -1112,12 +1112,12 @@ Lists all incident requests ticket templates. Useful for create incident tickets | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). Possible values are: . | Optional | -| limit | The maximum number of records to retrieve. Possible values are: . Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. Possible values are: . | Optional | -| page | The page number of the results to retrieve. Possible values are: . | Optional | -| description | The incident ticket template description. Used as a filtering argument. Possible values are: . | Optional | -| template_ids | A comma-separated list of incident template IDs. Used as a filtering argument. Possible values are: . | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| description | The incident ticket template description. Used as a filtering argument. | Optional | +| template_ids | A comma-separated list of incident template IDs. Used as a filtering argument. | Optional | #### Context Output @@ -1172,12 +1172,12 @@ Lists all task ticket templates. Useful for creating task tickets. The records a | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). Possible values are: . | Optional | -| limit | The maximum number of records to retrieve. Possible values are: . Default is 50. | Optional | -| page_size | The maximum number of records to retrieve per page. Possible values are: . | Optional | -| page | The page number of the results to retrieve. Possible values are: . | Optional | -| template_ids | A comma-separated list of task template IDs. Used as a filtering argument. Possible values are: . | Optional | -| task_name | The task ticket template name. Used as a filtering argument. Possible values are: . | Optional | +| query | The query to search by. For example: Status = "Draft" AND Impact = "1-Extensive/Widespread". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| template_ids | A comma-separated list of task template IDs. Used as a filtering argument. | Optional | +| task_name | The task ticket template name. Used as a filtering argument. | Optional | #### Context Output @@ -1256,9 +1256,10 @@ Gets remote data from a remote incident. This method does not update the current #### Context Output There is no context output for this command. + ### get-modified-remote-data *** -Gets the list of incidents that were modified since the last update time. Note that this method is here for debugging purposes. The get-modified-remote-data command is used as part of a Mirroring feature, which is available from version 6.1. +Gets the list of incidents that were modified since the last update time. Note that this method is here for debugging purposes. The get-modified-remote-data command is used as part of a Mirroring feature, which is available in Cortex XSOAR from version 6.1. #### Base Command @@ -1270,10 +1271,235 @@ Gets the list of incidents that were modified since the last update time. Note t | --- | --- | --- | | lastUpdate | A date string in local time representing the last time the incident was updated. The incident is only returned if it was modified after the last update time. | Optional | +#### Context Output + +There is no context output for this command. + + +### bmc-itsm-support-group-list + +*** +Lists all support groups. Useful for getting possible (Company, Support Organization, Support Group) triplets. + +#### Base Command + +`bmc-itsm-support-group-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| company | Company name. Used as a filtering argument. | Optional | +| support_organization | Support organization name. Used as a filtering argument. | Optional | +| support_group | Support group name. Used as a filtering argument. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| BmcITSM.SupportGroup.SupportGroupID | String | The support group ID. | +| BmcITSM.SupportGroup.Company | String | The support company. | +| BmcITSM.SupportGroup.SupportOrganization | String | The support organization. | +| BmcITSM.SupportGroup.SupportGroupName | String | The support group. | + +#### Command example +```!bmc-itsm-support-group-list limit=2``` +#### Context Example +```json +{ + "BmcITSM": { + "SupportGroup": [ + { + "Company": "Apex Global", + "SupportGroupID": "APX990000000029", + "SupportGroupName": "Apex Global - Facilities", + "SupportOrganization": "Facilities Support" + }, + { + "Company": "Calbro Services", + "SupportGroupID": "SGP000000000110", + "SupportGroupName": "Application Development / Deployment", + "SupportOrganization": "Application Support" + } + ] + } +} +``` + +#### Human Readable Output + +>### List support groups. +>Showing 2 records out of 15. +>|Support Group ID|Company|Support Organization|Support Group Name| +>|---|---|---|---| +>| APX990000000029 | Apex Global | Facilities Support | Apex Global - Facilities | +>| SGP000000000110 | Calbro Services | Application Support | Application Development / Deployment | + + +### bmc-itsm-work-order-template-list + +*** +Lists all work order templates. Useful for creating work orders. The records are retrieved by the query argument or by the filtering arguments. When using filtering arguments, each one defines a 'LIKE' operation and an 'AND' operator is used between them. To see the entire JSON, you can use the raw_response=true at the end of the command. + +#### Base Command + +`bmc-itsm-work-order-template-list` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| query | The query to search by. For example, query="Company like \"BMCOpsMonitoring\"". The query is used in addition to the existing arguments. See the BMC documentation for [building search qualifications](https://docs.bmc.com/docs/ars2008/building-qualifications-and-expressions-929630007.html). | Optional | +| limit | The maximum number of records to retrieve. Default is 50. | Optional | +| page_size | The maximum number of records to retrieve per page. | Optional | +| page | The page number of the results to retrieve. | Optional | +| template_ids | A comma-separated list of work order template GUIDs. Used as a filtering argument. | Optional | +| template_name | The work order template name. Used as a filtering argument. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| BmcITSM.WorkOrderTemplate.Id | String | The work order template ID. | +| BmcITSM.WorkOrderTemplate.Name | String | The work order template name. | +| BmcITSM.WorkOrderTemplate.GUID | String | The work order template GUID. | + +#### Command example +```!bmc-itsm-work-order-template-list limit=2``` +#### Context Example +```json +{ + "BmcITSM": { + "WorkOrderTemplate": [ + { + "GUID": "IDGCWH5RDMNSBARVRM5ERVRM5EKP11", + "Id": "000000000000002", + "Name": "Share Folder Access" + }, + { + "GUID": "IDGCWH5RDMNSBARVRNNGRVRNNGKY0X", + "Id": "000000000000003", + "Name": "New Share Folder Access" + } + ] + } +} +``` + +#### Human Readable Output + +>### List work order templates. +>Showing 2 records out of 9. +>|Id|Name|GUID| +>|---|---|---| +>| 000000000000002 | Share Folder Access | IDGCWH5RDMNSBARVRM5ERVRM5EKP11 | +>| 000000000000003 | New Share Folder Access | IDGCWH5RDMNSBARVRNNGRVRNNGKY0X | + + +### bmc-itsm-work-order-create + +*** +Creates a new work order ticket. + +#### Base Command + +`bmc-itsm-work-order-create` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| template_guid | The instance GUID of the template to use. The GUID can be retrieved by executing the bmc-itsm-work-order-template-list command. | Optional | +| first_name | Requester first name. | Optional | +| last_name | Requester last name. | Optional | +| customer_first_name | Customer first name. | Required | +| customer_last_name | Customer last name. | Required | +| customer_company | Customer company. | Required | +| customer_person_id | Customer person ID. Use it when customer first and last name pair is not unique. | Optional | +| summary | The work order summary. | Required | +| detailed_description | The work order ticket detailed description. | Required | +| status | The work order status. Possible values are: Assigned, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Required | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Example: additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent". | Optional | +| priority | The work order ticket priority. Possible values are: Critical, High, Medium, Low. | Required | +| work_order_type | The work order ticket type. Possible values are: General, Project. | Optional | +| location_company | The company associated with the task process. | Required | +| scedulded_start_date | The work order ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | +| scedulded_end_date | The work order ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| BmcITSM.WorkOrder.RequestID | String | The work order ticket unique Request ID. | +| BmcITSM.WorkOrder.DisplayID | String | The work order ticket unique Display ID. | +| BmcITSM.WorkOrder.CreateDate | Date | The work order ticket creation date time in UTC. | + +#### Command example +```!bmc-itsm-work-order-create customer_company="Calbro Services" customer_first_name="Scully" customer_last_name="Agent" detailed_description="Easy peasy work order" location_company="Calbro Services" priority=Low status=Pending summary="Easy peasy work order. No, really." customer_person_id=PPL000000000607 additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent"``` +#### Context Example +```json +{ + "BmcITSM": { + "WorkOrder": { + "CreateDate": "2024-02-07T08:08:23", + "DisplayID": "WO0000000001002", + "RequestID": "WO0000000000702" + } + } +} +``` + +#### Human Readable Output + +>### Work order ticket successfully created. +>|Create Date|Display ID|Request ID| +>|---|---|---| +>| 2024-02-07T08:08:23 | WO0000000001002 | WO0000000000702 | + + +### bmc-itsm-work-order-update + +*** +Updates the work order ticket. + +#### Base Command + +`bmc-itsm-work-order-update` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| request_id | The ID of the work order ticket to update. | Required | +| summary | The work order ticket summary. | Optional | +| detailed_description | The work order ticket detailed description. | Optional | +| priority | The work order ticket priority. Possible values are: Critical, High, Medium, Low. | Optional | +| status | The work order ticket status. Possible values are: Assigned, Pending, Waiting Approval, Planning, In Progress, Completed, Rejected, Cancelled, Closed. | Optional | +| status_reason | The reason for changing the ticket status. Possible values are: Initial Status, Awaiting Request Assignee, Client Hold, Client Additional Information Requested, Client Action Required, Support Contact Hold, Local Site Action Required, Purchase Order Approval, Supplier Delivery, Third Party Vendor Action Required, Infrastructure Change, Work not started, Successful, Successful with Issues, Cancelled by Requester, Cancelled by Support, Customer Close, System Close, System Close with Issues. | Optional | +| company | The company associated with the requester. By default it is determined by the logged in user. | Optional | +| location_company | The company associated with the work order process. | Optional | +| assignee | The full name of the employee the work order is assigned to. It can be retrieved by using the bmc-itsm-user-list command. | Optional | +| support_organization | The organization for the problem assignee's support organization. It makes up the second tier of the problem assignee's support organization data structure. The arguments support_organization, support_group should be provided together. It can be retrieved by using the bmc-itsm-support-group-list command. | Optional | +| support_group | The group for the problem assignee's support group. It makes up the third tier of the problem assignee's support organization data structure. The arguments support_organization, support_group should be provided together. It can be retrieved by using the bmc-itsm-support-group-list command. | Optional | +| work_order_type | The work order ticket type. Possible values are: General, Project. | Optional | +| additional_fields | The fields which are not present in the current argument list can be added here in the format "fieldname1=value;fieldname2=value". Example: additional_fields="Support Company=Calbro Services;Support Organization=IT Support;Support Group Name=Service Desk;Request Assignee=Scully Agent". | Optional | +| scedulded_start_date | The work order ticket scheduled future start date. For example, in 12 hours, in 7 days. | Optional | +| scedulded_end_date | The work order ticket scheduled future end date. For example, in 12 hours, in 7 days. | Optional | #### Context Output There is no context output for this command. +#### Command example +```!bmc-itsm-work-order-update request_id=WO0000000000701 summary="Updated summary" status="In Progress" support_organization="IT Support" support_group="Service Desk"``` +#### Human Readable Output + +>Work Order: WO0000000000701 was successfully updated. + + + ## Incident Mirroring You can enable incident mirroring between Cortex XSOAR incidents and BMC Helix ITSM corresponding events (available from Cortex XSOAR version 6.0.0). @@ -1292,3 +1518,4 @@ To set up the mirroring: Newly fetched incidents will be mirrored in the chosen direction. However, this selection does not affect existing incidents. **Important Note:** To ensure the mirroring works as expected, mappers are required, both for incoming and outgoing, to map the expected fields in Cortex XSOAR and BMC Helix ITSM. + diff --git a/Packs/BmcITSM/Integrations/BmcITSM/test_data/create_work_order.json b/Packs/BmcITSM/Integrations/BmcITSM/test_data/create_work_order.json new file mode 100644 index 000000000000..26632d657568 --- /dev/null +++ b/Packs/BmcITSM/Integrations/BmcITSM/test_data/create_work_order.json @@ -0,0 +1,14 @@ +{ + "values": { + "Request ID": "000000000000701", + "WorkOrder_ID": "WO0000000001001", + "Create Date": "2024-02-05T09:11:09.000+0000" + }, + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:WorkOrderInterface_Create" + } + ] + } +} \ No newline at end of file diff --git a/Packs/BmcITSM/Integrations/BmcITSM/test_data/get_work_order.json b/Packs/BmcITSM/Integrations/BmcITSM/test_data/get_work_order.json new file mode 100644 index 000000000000..54bbc08e647f --- /dev/null +++ b/Packs/BmcITSM/Integrations/BmcITSM/test_data/get_work_order.json @@ -0,0 +1,215 @@ +{ + "values": { + "Request ID": "WO0000000000701|WO0000000000701", + "Submitter": "Scully_Agent", + "Submit Date": "2024-02-05T09:11:09.000+0000", + "Assigned To": null, + "Last Modified Date": "2024-02-05T09:11:10.000+0000", + "Status": "Assigned", + "Work Order Template Used": "?", + "Assignee Groups": "1000000005;'Scully_Agent';", + "InstanceId": "AGGHKPQIDC46ZASI3L8LSI3L8L7B5G", + "Record ID": "AGGHKPQIDC46ZASI3L8LSI3L8L7B5G|AGGHKPQIDC46ZASI3L8LSI3L8L7B5G", + "Vendor Assignee Groups": null, + "Vendor Assignee Groups_parent": null, + "Assignee Groups_parent": "", + "Department": "Customer Service", + "Site Group": "United States", + "Region": "Americas", + "Business Service": null, + "LookupKeyword": "MAINWORKORDER", + "Site": "Boston Support Center", + "WO Type Field 1": null, + "WO Type Field 2": null, + "WO Type Field 3": null, + "WO Type Field 4": null, + "WO Type Field 5": null, + "WO Type Field 6": null, + "WO Type Field 7": null, + "WO Type Field 8": null, + "WO Type Field 9": null, + "SRAttachment": null, + "Customer Middle Name": null, + "z1D_Command": null, + "z1D_WorklogDetails": null, + "SRInstanceID": null, + "zTmpEventGUID": null, + "CustomerFullName": "Scully Agent", + "z1D_Activity Type*": null, + "z1D_Summary": null, + "z1D_Details": null, + "z1D_Secure_Log": null, + "z1D_View_Access": null, + "Attachment 1": null, + "WorkOrderID": "WO0000000000701", + "SRMSRegistryInstanceID": null, + "SRMSAOIGuid": null, + "SRID": null, + "TemplateID": null, + "z1D_CommunicationSource": null, + "z1D_ActivityDate_tab": null, + "z1D_WorkInfoViewAccess": null, + "z1D Action WO1": null, + "z1D Action WO2": null, + "Needs Attention": null, + "Requestor_By_ID": "Scully_Agent", + "ClientLocale": null, + "WO Type Field 10": null, + "WO Type Field 11": null, + "WO Type Field 12": null, + "WO Type Field 13": null, + "WO Type Field 14": null, + "WO Type Field 15": null, + "WO Type Field 16": null, + "WO Type Field 17": null, + "WO Type Field 18": null, + "WO Type Field 19": null, + "WO Type Field 20": null, + "WO Type Field 21": null, + "WO Type Field 22": null, + "WO Type Field 23": null, + "WO Type Field 24": null, + "WO Type Field 25": null, + "WO Type Field 26": null, + "WO Type Field 27": null, + "WO Type Field 28": null, + "WO Type Field 29": null, + "WO Type Field 30": null, + "Previous_ServiceCI_ReconID": null, + "z1D_SR_Instanceid": null, + "WO Type Field 10 Label": null, + "WO Type Field 11 Label": null, + "WO Type Field 12 Label": null, + "WO Type Field 13 Label": null, + "WO Type Field 14 Label": null, + "WO Type Field 15 Label": null, + "WO Type Field 16 Label": null, + "WO Type Field 17 Label": null, + "WO Type Field 18 Label": null, + "WO Type Field 19 Label": null, + "WO Type Field 20 Label": null, + "WO Type Field 21 Label": null, + "WO Type Field 22 Label": null, + "WO Type Field 23 Label": null, + "WO Type Field 24 Label": null, + "WO Type Field 25 Label": null, + "WO Type Field 26 Label": null, + "WO Type Field 27 Label": null, + "WO Type Field 28 Label": null, + "WO Type Field 29 Label": null, + "WO Type Field 30 Label": null, + "z1D_WorkInfoSubmitter": null, + "AttachmentSourceFormName": null, + "AttachmentSourceGUID": null, + "AttachmentSubmitter": null, + "SRWorkInfoType": null, + "z1D_ConfirmGroup": null, + "CreatedFromBackEndSynchWI": null, + "WO Type Field 48": null, + "WO Type Field 49": null, + "WO Type Field 50": null, + "WO Type Field 51": null, + "WO Type Field 48 Label": null, + "WO Type Field 49 Label": null, + "WO Type Field 50 Label": null, + "WO Type Field 51 Label": null, + "Chat Session ID": null, + "Broker Vendor Name": null, + "NeedsAttentionCCS_Setting": "false", + "Automation Status": "Manual", + "RequestCreatedFromDWP": "No", + "DWP_SRID": null, + "DWP_SRInstanceID": null, + "WO Type Field 01 Label": null, + "WO Type Field 02 Label": null, + "WO Type Field 03 Label": null, + "WO Type Field 04 Label": null, + "WO Type Field 05 Label": null, + "WO Type Field 06 Label": null, + "WO Type Field 07 Label": null, + "WO Type Field 08 Label": null, + "WO Type Field 09 Label": null, + "z1D Char09": null, + "CI_DatasetId": "BMC.ASSET", + "CI_ReconId": null, + "Description": "Sample WO 20240205", + "Location Company": "Calbro Services", + "Organization": "Information Technology", + "Support Organization": "IT Support", + "Support Group Name": "Service Desk", + "Last Name": "Agent", + "First Name": "Scully", + "Middle Initial": null, + "VIP": "No", + "Chg Location Address": "350 Seventh Avenue, 18th Floor\r\nBoston, Massachusetts 02101\r\nUnited States", + "Internet E-mail": null, + "Phone Number": "###", + "z1D Char01": null, + "Categorization Tier 1": null, + "Categorization Tier 2": null, + "Categorization Tier 3": null, + "z1D Char02": null, + "z1D Char03": null, + "z1D Char04": null, + "z1D_Action": null, + "z1D Integer01": null, + "Support Group ID": "SGP000000000011", + "Person ID": "PPL000000000607", + "Company": "Calbro Services", + "z1D Char05": null, + "z1D Char06": null, + "Add Request For:": "Individual", + "z1D Char07": null, + "z1D Char08": null, + "z1D Integer02": null, + "z1D Integer03": null, + "z1D Char10": null, + "Status Reason": null, + "Detailed Description": "Sample WO 20240205", + "Priority": "Low", + "Work Order Type": "General", + "Work Order ID": "WO0000000001001", + "Company3": "Calbro Services", + "Requestor ID": "Scully_Agent", + "Support Group Name2": null, + "Support Organization2": null, + "Actual Start Date": null, + "Scheduled Start Date": null, + "Scheduled End Date": null, + "Actual End Date": null, + "Number of Attachments": null, + "CAB Manager ( Change Co-ord )": "Edward Agent", + "CAB Manager Login": "Edward Agent", + "Support Group ID 2": "SGP000000000011", + "Requested By Person ID": "PPL000000000607", + "z1D_Worklog Type": null, + "Product Cat Tier 1(2)": null, + "Product Cat Tier 2 (2)": null, + "Product Cat Tier 3 (2)": null, + "Completed Date": null, + "Product Name (2)": null, + "Product Model/Version (2)": null, + "Manufacturer (2)": null, + "ASORG": "IT Support", + "ASCPY": "Calbro Services", + "ASGRP": "Service Desk", + "ASCHG": "Cyrus Agent", + "ASLOGID": "Cyrus Agent", + "ASGRPID": "SGP000000000011", + "Customer Person ID": "PPL000000000607", + "Customer First Name": "Scully", + "Customer Last Name": "Agent", + "Customer Company": "Calbro Services", + "Customer Organization": "Information Technology", + "Customer Department": "Customer Service", + "Customer Internet E-mail": null, + "Customer Phone Number": "###" + }, + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:WorkOrderInterface/WO0000000000701%7CWO0000000000701" + } + ] + } +} \ No newline at end of file diff --git a/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_support_group.json b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_support_group.json new file mode 100644 index 000000000000..8dc5e7871da5 --- /dev/null +++ b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_support_group.json @@ -0,0 +1,160 @@ +{ + "entries": [ + { + "values": { + "Support Group ID": "APX990000000029", + "Submitter": "Remedy Application Service", + "Submit Date": "2023-04-27T20:05:08.000+0000", + "Assigned To": null, + "Last Modified By": "Demo", + "Last Modified Date": "2023-04-28T01:14:00.000+0000", + "Status": "Enabled", + "Short Description": ".", + "Notifier Listening": "Not Listening", + "Assignee Groups": "1000000042;1000000043;", + "instanceId": "AGGADGJBG3LAPX99SZPOQRSZPOVUT0", + "Record ID": "AGGADGJBG3LAPX99SZPOQRSZPOVUT0", + "Vendor Assignee Groups": null, + "Vendor Assignee Groups_parent": null, + "Assignee Groups_parent": "", + "z1G InitComplete": null, + "z1G_DefaultCompany": null, + "z1G_UnrestrictedAccessMember": null, + "z1G_Global_HNS": null, + "Permission_Group_Enabled": "Yes", + "DataTags": "BWFData", + "z1D_schemaID": null, + "z1D_DefaultCompanyAction": null, + "z1D_DefaultCompanyInteger": null, + "z1D_SupportGroupRole": null, + "z1D_Char04": null, + "DisableGroupNotification": "No", + "GroupNotificationEmail": null, + "Notification_Locale": "en_US", + "z1D_ConfirmGroup": null, + "Parent Group": null, + "Confidential Support Group": "No", + "Company_SortOrder": 100, + "Description": null, + "Company": "Apex Global", + "Support Organization": "Facilities Support", + "Support Group Name": "Apex Global - Facilities", + "z1D Char01": null, + "z1D Char02": null, + "z1D Action": null, + "z1D Integer01": null, + "z1D Lastcount": null, + "z1D Role": null, + "Assigned Support Company": null, + "z1D Date01": null, + "Shifts Flag": "No", + "Business Workdays Tag": null, + "Business Holidays Tag": null, + "Support Group Role": "Line of Business", + "Uses SLA": "Yes", + "Uses OLA": "Yes", + "On Call Group Flag": "No", + "z1D Permission Group ID": null, + "z1D Permission Group List": null, + "z1D Association Action01": null, + "Vendor Group": "No", + "Navigation Menu01": "Apex Global", + "Navigation Menu02": null, + "Navigation Menu03": null, + "z1D_Display_Locale": null, + "z1D Association Action01_locale": null + }, + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/CTM:Support%20Group/APX990000000029" + } + ] + } + }, + { + "values": { + "Support Group ID": "SGP000000000110", + "Submitter": "activationuser", + "Submit Date": "2023-05-10T17:34:37.000+0000", + "Assigned To": null, + "Last Modified By": "Remedy Application Service", + "Last Modified Date": "2023-05-10T17:34:37.000+0000", + "Status": "Enabled", + "Short Description": ".", + "Notifier Listening": "Not Listening", + "Assignee Groups": "1000000001;", + "instanceId": "AGGCWH5RDMNSBARU64APRU64APAVH7", + "Record ID": "AGGCWH5RDMNSBARU64APRU64APAVH7", + "Vendor Assignee Groups": null, + "Vendor Assignee Groups_parent": null, + "Assignee Groups_parent": "", + "z1G InitComplete": null, + "z1G_DefaultCompany": null, + "z1G_UnrestrictedAccessMember": null, + "z1G_Global_HNS": null, + "Permission_Group_Enabled": "Yes", + "DataTags": null, + "z1D_schemaID": null, + "z1D_DefaultCompanyAction": null, + "z1D_DefaultCompanyInteger": null, + "z1D_SupportGroupRole": null, + "z1D_Char04": null, + "DisableGroupNotification": "No", + "GroupNotificationEmail": null, + "Notification_Locale": null, + "z1D_ConfirmGroup": null, + "Parent Group": null, + "Confidential Support Group": "No", + "Company_SortOrder": 100, + "Description": null, + "Company": "Calbro Services", + "Support Organization": "Application Support", + "Support Group Name": "Application Development / Deployment", + "z1D Char01": null, + "z1D Char02": null, + "z1D Action": null, + "z1D Integer01": null, + "z1D Lastcount": null, + "z1D Role": null, + "Assigned Support Company": null, + "z1D Date01": null, + "Shifts Flag": "No", + "Business Workdays Tag": null, + "Business Holidays Tag": null, + "Support Group Role": "Tier 1", + "Uses SLA": "Yes", + "Uses OLA": "Yes", + "On Call Group Flag": "No", + "z1D Permission Group ID": null, + "z1D Permission Group List": null, + "z1D Association Action01": null, + "Vendor Group": "No", + "Navigation Menu01": "Calbro Services", + "Navigation Menu02": null, + "Navigation Menu03": null, + "z1D_Display_Locale": null, + "z1D Association Action01_locale": null + }, + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/CTM:Support%20Group/SGP000000000110" + } + ] + } + } + ], + "_links": { + "next": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/CTM:Support%20Group?offset=2&limit=2" + } + ], + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/CTM:Support%20Group?limit=2" + } + ] + } +} \ No newline at end of file diff --git a/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_support_group_filter.json b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_support_group_filter.json new file mode 100644 index 000000000000..dcf6ed9b50fc --- /dev/null +++ b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_support_group_filter.json @@ -0,0 +1,83 @@ +{ + "entries": [ + { + "values": { + "Support Group ID": "APX990000000029", + "Submitter": "Remedy Application Service", + "Submit Date": "2023-04-27T20:05:08.000+0000", + "Assigned To": null, + "Last Modified By": "Demo", + "Last Modified Date": "2023-04-28T01:14:00.000+0000", + "Status": "Enabled", + "Short Description": ".", + "Notifier Listening": "Not Listening", + "Assignee Groups": "1000000042;1000000043;", + "instanceId": "AGGADGJBG3LAPX99SZPOQRSZPOVUT0", + "Record ID": "AGGADGJBG3LAPX99SZPOQRSZPOVUT0", + "Vendor Assignee Groups": null, + "Vendor Assignee Groups_parent": null, + "Assignee Groups_parent": "", + "z1G InitComplete": null, + "z1G_DefaultCompany": null, + "z1G_UnrestrictedAccessMember": null, + "z1G_Global_HNS": null, + "Permission_Group_Enabled": "Yes", + "DataTags": "BWFData", + "z1D_schemaID": null, + "z1D_DefaultCompanyAction": null, + "z1D_DefaultCompanyInteger": null, + "z1D_SupportGroupRole": null, + "z1D_Char04": null, + "DisableGroupNotification": "No", + "GroupNotificationEmail": null, + "Notification_Locale": "en_US", + "z1D_ConfirmGroup": null, + "Parent Group": null, + "Confidential Support Group": "No", + "Company_SortOrder": 100, + "Description": null, + "Company": "Apex Global", + "Support Organization": "Facilities Support", + "Support Group Name": "Apex Global - Facilities", + "z1D Char01": null, + "z1D Char02": null, + "z1D Action": null, + "z1D Integer01": null, + "z1D Lastcount": null, + "z1D Role": null, + "Assigned Support Company": null, + "z1D Date01": null, + "Shifts Flag": "No", + "Business Workdays Tag": null, + "Business Holidays Tag": null, + "Support Group Role": "Line of Business", + "Uses SLA": "Yes", + "Uses OLA": "Yes", + "On Call Group Flag": "No", + "z1D Permission Group ID": null, + "z1D Permission Group List": null, + "z1D Association Action01": null, + "Vendor Group": "No", + "Navigation Menu01": "Apex Global", + "Navigation Menu02": null, + "Navigation Menu03": null, + "z1D_Display_Locale": null, + "z1D Association Action01_locale": null + }, + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/CTM:Support%20Group/APX990000000029" + } + ] + } + } + ], + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/CTM:Support%20Group?q=%27Company%27%20like%20%22%25Apex%25%22" + } + ] + } +} \ No newline at end of file diff --git a/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_tickets_work_order.json b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_tickets_work_order.json new file mode 100644 index 000000000000..8f11d65c86bd --- /dev/null +++ b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_tickets_work_order.json @@ -0,0 +1,226 @@ +{ + "entries": [ + { + "values": { + "Request ID": "WO0000000000003|WO0000000000003", + "Submitter": "Remedy Application Service", + "Submit Date": "2023-06-05T07:25:09.000+0000", + "Assigned To": null, + "Last Modified Date": "2023-06-05T07:25:10.000+0000", + "Status": "Assigned", + "Work Order Template Used": "New Share Folder Access", + "Assignee Groups": "1000000005;'Arthur Agent';", + "InstanceId": "IDGCWH5RDMNSBARVRRJXRVRRJXLQUZ", + "Record ID": "IDGCWH5RDMNSBARVRRJXRVRRJXLQUZ|IDGCWH5RDMNSBARVRRJXRVRRJXLQUZ", + "Vendor Assignee Groups": null, + "Vendor Assignee Groups_parent": null, + "Assignee Groups_parent": "", + "Department": "Customer Service", + "Site Group": "Amsterdam", + "Region": "Europe", + "Business Service": null, + "LookupKeyword": "MAINWORKORDER", + "Site": "Amsterdam Support Center", + "WO Type Field 1": "TestA16", + "WO Type Field 2": "Sharefolder", + "WO Type Field 3": "read", + "WO Type Field 4": null, + "WO Type Field 5": null, + "WO Type Field 6": null, + "WO Type Field 7": null, + "WO Type Field 8": null, + "WO Type Field 9": null, + "SRAttachment": null, + "Customer Middle Name": null, + "z1D_Command": null, + "z1D_WorklogDetails": null, + "SRInstanceID": "SRGCWH5RDMNSBARVRRJWRVRRJWLQTI", + "zTmpEventGUID": "CAGCWH5RDMNSBARVRRJXRVRRJXLQXE", + "CustomerFullName": "Arthur Agent", + "z1D_Activity Type*": null, + "z1D_Summary": null, + "z1D_Details": null, + "z1D_Secure_Log": null, + "z1D_View_Access": null, + "Attachment 1": null, + "WorkOrderID": "WO0000000000003", + "SRMSRegistryInstanceID": "SR0011439CCAD4ec8UQwCkOLAQlQAA", + "SRMSAOIGuid": "AGGCWH5RDMNSBARVRRJXRVRRJXLQUY", + "SRID": "REQ000000000007", + "TemplateID": "IDGCWH5RDMNSBARVRNNGRVRNNGKY0X", + "z1D_CommunicationSource": null, + "z1D_ActivityDate_tab": null, + "z1D_WorkInfoViewAccess": null, + "z1D Action WO1": null, + "z1D Action WO2": null, + "Needs Attention": null, + "Requestor_By_ID": "Arthur Agent", + "ClientLocale": null, + "WO Type Field 10": null, + "WO Type Field 11": null, + "WO Type Field 12": null, + "WO Type Field 13": null, + "WO Type Field 14": null, + "WO Type Field 15": null, + "WO Type Field 16": null, + "WO Type Field 17": null, + "WO Type Field 18": null, + "WO Type Field 19": null, + "WO Type Field 20": null, + "WO Type Field 21": null, + "WO Type Field 22": null, + "WO Type Field 23": null, + "WO Type Field 24": null, + "WO Type Field 25": null, + "WO Type Field 26": null, + "WO Type Field 27": null, + "WO Type Field 28": null, + "WO Type Field 29": null, + "WO Type Field 30": null, + "Previous_ServiceCI_ReconID": null, + "z1D_SR_Instanceid": null, + "WO Type Field 10 Label": ".", + "WO Type Field 11 Label": ".", + "WO Type Field 12 Label": ".", + "WO Type Field 13 Label": ".", + "WO Type Field 14 Label": ".", + "WO Type Field 15 Label": ".", + "WO Type Field 16 Label": ".", + "WO Type Field 17 Label": ".", + "WO Type Field 18 Label": ".", + "WO Type Field 19 Label": ".", + "WO Type Field 20 Label": ".", + "WO Type Field 21 Label": ".", + "WO Type Field 22 Label": ".", + "WO Type Field 23 Label": ".", + "WO Type Field 24 Label": ".", + "WO Type Field 25 Label": ".", + "WO Type Field 26 Label": ".", + "WO Type Field 27 Label": ".", + "WO Type Field 28 Label": ".", + "WO Type Field 29 Label": ".", + "WO Type Field 30 Label": ".", + "z1D_WorkInfoSubmitter": null, + "AttachmentSourceFormName": null, + "AttachmentSourceGUID": null, + "AttachmentSubmitter": null, + "SRWorkInfoType": null, + "z1D_ConfirmGroup": null, + "CreatedFromBackEndSynchWI": null, + "WO Type Field 48": null, + "WO Type Field 49": null, + "WO Type Field 50": null, + "WO Type Field 51": null, + "WO Type Field 48 Label": ".", + "WO Type Field 49 Label": ".", + "WO Type Field 50 Label": ".", + "WO Type Field 51 Label": ".", + "Chat Session ID": null, + "Broker Vendor Name": null, + "NeedsAttentionCCS_Setting": "false", + "Automation Status": "Manual", + "RequestCreatedFromDWP": "No", + "DWP_SRID": null, + "DWP_SRInstanceID": null, + "WO Type Field 01 Label": "Username", + "WO Type Field 02 Label": "Sharefolder Name", + "WO Type Field 03 Label": "Access Type", + "WO Type Field 04 Label": ".", + "WO Type Field 05 Label": ".", + "WO Type Field 06 Label": ".", + "WO Type Field 07 Label": ".", + "WO Type Field 08 Label": ".", + "WO Type Field 09 Label": ".", + "z1D Char09": null, + "CI_DatasetId": "BMC.ASSET", + "CI_ReconId": null, + "Description": "New Share Folder Access", + "Location Company": "Calbro Services", + "Organization": "Information Technology", + "Support Organization": "IT Support", + "Support Group Name": "Service Desk", + "Last Name": "Agent", + "First Name": "Arthur", + "Middle Initial": null, + "VIP": "No", + "Chg Location Address": "Boeing Avenue 245 \r\nSchiphol-Rijk, Amsterdam 1119 PD \r\nNetherlands", + "Internet E-mail": "info@bmc.com", + "Phone Number": "###", + "z1D Char01": null, + "Categorization Tier 1": null, + "Categorization Tier 2": null, + "Categorization Tier 3": null, + "z1D Char02": null, + "z1D Char03": null, + "z1D Char04": null, + "z1D_Action": null, + "z1D Integer01": null, + "Support Group ID": "SGP000000000011", + "Person ID": "PPL000000000106", + "Company": "Calbro Services", + "z1D Char05": null, + "z1D Char06": null, + "Add Request For:": "Individual", + "z1D Char07": null, + "z1D Char08": null, + "z1D Integer02": null, + "z1D Integer03": null, + "z1D Char10": null, + "Status Reason": null, + "Detailed Description": "New Share Folder Access ", + "Priority": "Low", + "Work Order Type": "General", + "Work Order ID": "WO0000000000009", + "Company3": "Calbro Services", + "Requestor ID": "Arthur Agent", + "Support Group Name2": null, + "Support Organization2": null, + "Actual Start Date": null, + "Scheduled Start Date": null, + "Scheduled End Date": null, + "Actual End Date": null, + "Number of Attachments": null, + "CAB Manager ( Change Co-ord )": "Arthur Agent", + "CAB Manager Login": "Arthur Agent", + "Support Group ID 2": "SGP000000000011", + "Requested By Person ID": "PPL000000000106", + "z1D_Worklog Type": null, + "Product Cat Tier 1(2)": null, + "Product Cat Tier 2 (2)": null, + "Product Cat Tier 3 (2)": null, + "Completed Date": null, + "Product Name (2)": null, + "Product Model/Version (2)": null, + "Manufacturer (2)": null, + "ASORG": "IT Support", + "ASCPY": "Calbro Services", + "ASGRP": "Service Desk", + "ASCHG": "Test Admin", + "ASLOGID": "testadmin", + "ASGRPID": "SGP000000000011", + "Customer Person ID": "PPL000000000106", + "Customer First Name": "Arthur", + "Customer Last Name": "Agent", + "Customer Company": "Calbro Services", + "Customer Organization": "Information Technology", + "Customer Department": "Customer Service", + "Customer Internet E-mail": "info@bmc.com", + "Customer Phone Number": "###" + }, + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:WorkOrderInterface/WO0000000000003%7CWO0000000000003" + } + ] + } + } + ], + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:WorkOrderInterface?limit=2&q=%27Work%20Order%20ID%27%20like%20%22WO0000000000009%22" + } + ] + } +} \ No newline at end of file diff --git a/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_work_order_template.json b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_work_order_template.json new file mode 100644 index 000000000000..bbc42413de01 --- /dev/null +++ b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_work_order_template.json @@ -0,0 +1,522 @@ +{ + "entries": [ + { + "values": { + "Request ID": "000000000000002", + "Submitter": "Arthur Agent", + "Submit Date": "2023-06-05T05:45:00.000+0000", + "Assigned To": null, + "Last Modified By": "Arthur Agent", + "Last Modified Date": "2023-06-05T06:01:11.000+0000", + "Status": "Enabled", + "Template Name": "Share Folder Access", + "Notifier Listening": "Not Listening", + "Assignee Groups": "15031;1000000001;", + "GUID": "IDGCWH5RDMNSBARVRM5ERVRM5EKP11", + "Record ID": "AGGCWH5RDMNSBARVRMNARVRMNAKQ5G", + "Vendor Assignee Groups": null, + "Vendor Assignee Groups_parent": null, + "Assignee Groups_parent": "", + "z1G_DefaultCompany": null, + "z1G_Global_AST_ProductionDataSetID": null, + "z1G_UnrestrictedAccessMember": null, + "z1G_TMSDirtyStructureFlag": null, + "Notes": null, + "zTmpAuditAction": null, + "zTmpAuditOldStatus": null, + "zTmpAuditWorkspace": null, + "zTmpNonAuditable": null, + "zTmpTableLoadedMask": null, + "zTmpRequestID": null, + "Change in Sequence": null, + "z1D_Integer": null, + "z1D_ChildSequenceChange": null, + "z1D_SelectedTaskId": null, + "z1D_Task Event Code": null, + "z1D_TaskSubtype": null, + "z1D_Task instance Id": null, + "z1D_Task Id": null, + "z1D_Process Id": null, + "z1D_Task Event Info 1": null, + "z1D_Task Event Info 2": null, + "z1D_Task Event Info 3": null, + "z1D_Task Event Info 4": null, + "z1D_Task Event Info 5": null, + "z1D_Task Event Info 6": null, + "z1D_NextSequence": null, + "z1D_SelectedTaskGroupId": null, + "z1D_TypeSelector": null, + "z1D_ChildTaskTG": null, + "zTmpInstanceNum": null, + "zTmpPredecessorID": null, + "zTmpSuccessorID": null, + "zTmpFlowID": null, + "zTmpStart": null, + "zTmp_SelectOne": null, + "Name": "Share Folder Access", + "Category": null, + "z1D_TaskGroupType": null, + "z1D_Child Type": null, + "Product Categorization Tier 1": null, + "Product Categorization Tier 2": null, + "Product Categorization Tier 3": null, + "Site Group": null, + "Region": null, + "Business Service": null, + "Product Name": null, + "Site": null, + "z1D_Dirty Flag": null, + "z1D_DirtyFlagAssociations": null, + "Topic": null, + "MappedTemplateInstanceId": "IDGCWH5RDMNSBARVRM5ERVRM5EKP11", + "MappedTemplate_Name": "Share Folder Access", + "MappedTemplatedDescription": "Share Folder Access", + "Used_by_SRMS": null, + "Assignment_Accelerator_Assignee": null, + "Assignment_Accelerator_Manager": null, + "DataTags": null, + "z1D_StatusQuerySelection": null, + "z1D Current Database Status": null, + "z1D_TaskTableRefreshDone": null, + "z1D_DefaultCompanyAction": null, + "z1D_DefaultCompanyInteger": null, + "WO Type Field 10": null, + "WO Type Field 11": null, + "WO Type Field 12": null, + "WO Type Field 13": null, + "WO Type Field 14": null, + "WO Type Field 15": null, + "WO Type Field 16": null, + "WO Type Field 17": null, + "WO Type Field 18": null, + "WO Type Field 19": null, + "WO Type Field 20": null, + "WO Type Field 21": null, + "WO Type Field 22": null, + "WO Type Field 23": null, + "WO Type Field 24": 0, + "WO Type Field 25": null, + "WO Type Field 26": null, + "WO Type Field 27": null, + "WO Type Field 28": null, + "WO Type Field 29": null, + "WO Type Field 30": null, + "WO Type Field 10 Label": ".", + "WO Type Field 11 Label": ".", + "WO Type Field 12 Label": ".", + "WO Type Field 13 Label": ".", + "WO Type Field 14 Label": ".", + "WO Type Field 15 Label": ".", + "WO Type Field 16 Label": ".", + "WO Type Field 17 Label": ".", + "WO Type Field 18 Label": ".", + "WO Type Field 19 Label": ".", + "WO Type Field 20 Label": ".", + "WO Type Field 21 Label": ".", + "WO Type Field 22 Label": ".", + "WO Type Field 23 Label": ".", + "WO Type Field 24 Label": ".", + "WO Type Field 25 Label": ".", + "WO Type Field 26 Label": ".", + "WO Type Field 27 Label": ".", + "WO Type Field 28 Label": ".", + "WO Type Field 29 Label": ".", + "WO Type Field 30 Label": ".", + "z1D_ExternalQual": null, + "z1D_remove_colcount": 0, + "z1D_ImportBypass": null, + "z1D_Int_ColCount": null, + "z1D_company": "BMCOpsMonitoring", + "z1D_OldLocationCompanyGroupID": null, + "z1D_NewLocationCompanyGroupID": "1000000001", + "ASLOGID": null, + "Parent_Job_GUID": null, + "z1D_Company_Get": "BMCOpsMonitoring", + "z1G_WOTaskDisplayOptionSettings": "Yes", + "z1D_ConfirmGroup": null, + "z1D_FLagOpenWindow": null, + "z1D template": null, + "z1D ExtQualification": null, + "Mark Records for Delete": null, + "ObsoleteDataDelete": null, + "WO Type Field 48": null, + "WO Type Field 49": null, + "WO Type Field 50": null, + "WO Type Field 51": null, + "WO Type Field 48 Label": ".", + "WO Type Field 49 Label": ".", + "WO Type Field 50 Label": ".", + "WO Type Field 51 Label": ".", + "z1D ValidateInfo": null, + "z1d_Search_Template_Name": null, + "Automation Status": "Manual", + "z1D_FTS_ScanTime": -3600, + "zTmp_ExpCommonInstanceID": null, + "WO Type Field 1 Label": "Username", + "WO Type Field 2 Label": "Sharefolder Name", + "WO Type Field 3 Label": "Access Type", + "WO Type Field 4 Label": ".", + "WO Type Field 5 Label": ".", + "WO Type Field 6 Label": ".", + "WO Type Field 7 Label": ".", + "WO Type Field 8 Label": ".", + "WO Type Field 9 Label": ".", + "WO Type Field 1 Value": null, + "WO Type Field 2 Value": null, + "WO Type Field 3 Value": null, + "WO Type Field 4 Value": null, + "WO Type Field 5 Value": null, + "WO Type Field 6 Value": null, + "WO Type Field 7 Value": null, + "WO Type Field 8 Value": null, + "WO Type Field 9 Value": null, + "z1D Char09": null, + "z1D_Integer_2": null, + "Application GUID": null, + "Property Value": null, + "CI_ReconId": null, + "Summary": "Share Folder Access", + "Location Company": "BMCOpsMonitoring", + "Support Organization": null, + "Support Group Name": null, + "Chg Location Address": null, + "z1D Char01": null, + "Categorization Tier 1": null, + "Categorization Tier 2": null, + "Categorization Tier 3": null, + "z1D Char02": null, + "z1D Char03": null, + "z1D Char04": null, + "z1D Action": null, + "z1D Integer01": null, + "Support Group ID": null, + "Company": "Calbro Services", + "z1D Char05": null, + "z1D Char06": null, + "Add Request For:": "Organization", + "z1D Char07": null, + "z1D Char08": null, + "z1D Char29": null, + "z1D Char10": null, + "z1D Char11": null, + "z1D Char12": null, + "z1D Char13": null, + "z1D Char14": null, + "z1D Lastcount": null, + "z1D Char15": null, + "Work Order Type": "General", + "Company3": null, + "z1D Char16": null, + "CAB Manager ( Change Co-ord )": null, + "CAB Manager Login": null, + "z1D Char17": null, + "z1D Date03": null, + "z1D Date04": null, + "Author Group ID": null, + "z1D Char18": null, + "z1D Char19": null, + "z1D Char20": null, + "z1D Char21": null, + "z1D Char22": null, + "Product Cat Tier 1(2)": null, + "Product Cat Tier 2 (2)": null, + "Product Cat Tier 3 (2)": null, + "Authoring Group": null, + "Authoring Organization": null, + "Authoring Company": null, + "z1D Authoring Company": null, + "z1D Authoring Organization": null, + "z1D Authoring Group": null, + "z1D Char23": null, + "z1D Permission Group ID": null, + "z1D Permission Group List": null, + "z1D Char24": null, + "z1D Char25": null, + "Product Name (2)": null, + "Product Model/Version (2)": null, + "Manufacturer (2)": null, + "z1D IC Status": null, + "z1D Task Action": null, + "ASORG": null, + "ASCPY": null, + "ASGRP": null, + "ASCHG": null, + "ASGRPID": null, + "z1D Task Exist": null, + "z1D Task Status": null + }, + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:Template/000000000000002" + } + ] + } + }, + { + "values": { + "Request ID": "000000000000003", + "Submitter": "Arthur Agent", + "Submit Date": "2023-06-05T06:07:52.000+0000", + "Assigned To": null, + "Last Modified By": "Arthur Agent", + "Last Modified Date": "2023-06-12T12:14:30.000+0000", + "Status": "Enabled", + "Template Name": "New Share Folder Access", + "Notifier Listening": "Not Listening", + "Assignee Groups": "1000000001;", + "GUID": "IDGCWH5RDMNSBARVRNNGRVRNNGKY0X", + "Record ID": "AGGCWH5RDMNSBARVRNPERVRNPEKYLI", + "Vendor Assignee Groups": null, + "Vendor Assignee Groups_parent": null, + "Assignee Groups_parent": "", + "z1G_DefaultCompany": null, + "z1G_Global_AST_ProductionDataSetID": null, + "z1G_UnrestrictedAccessMember": null, + "z1G_TMSDirtyStructureFlag": null, + "Notes": "New Share Folder Access", + "zTmpAuditAction": null, + "zTmpAuditOldStatus": null, + "zTmpAuditWorkspace": null, + "zTmpNonAuditable": null, + "zTmpTableLoadedMask": null, + "zTmpRequestID": null, + "Change in Sequence": null, + "z1D_Integer": null, + "z1D_ChildSequenceChange": null, + "z1D_SelectedTaskId": null, + "z1D_Task Event Code": null, + "z1D_TaskSubtype": null, + "z1D_Task instance Id": null, + "z1D_Task Id": null, + "z1D_Process Id": null, + "z1D_Task Event Info 1": null, + "z1D_Task Event Info 2": null, + "z1D_Task Event Info 3": null, + "z1D_Task Event Info 4": null, + "z1D_Task Event Info 5": null, + "z1D_Task Event Info 6": null, + "z1D_NextSequence": null, + "z1D_SelectedTaskGroupId": null, + "z1D_TypeSelector": null, + "z1D_ChildTaskTG": null, + "zTmpInstanceNum": null, + "zTmpPredecessorID": null, + "zTmpSuccessorID": null, + "zTmpFlowID": null, + "zTmpStart": null, + "zTmp_SelectOne": null, + "Name": "New Share Folder Access", + "Category": null, + "z1D_TaskGroupType": null, + "z1D_Child Type": null, + "Product Categorization Tier 1": null, + "Product Categorization Tier 2": null, + "Product Categorization Tier 3": null, + "Site Group": null, + "Region": null, + "Business Service": null, + "Product Name": null, + "Site": null, + "z1D_Dirty Flag": null, + "z1D_DirtyFlagAssociations": null, + "Topic": null, + "MappedTemplateInstanceId": "IDGCWH5RDMNSBARVRNNGRVRNNGKY0X", + "MappedTemplate_Name": "New Share Folder Access", + "MappedTemplatedDescription": "New Share Folder Access", + "Used_by_SRMS": null, + "Assignment_Accelerator_Assignee": null, + "Assignment_Accelerator_Manager": null, + "DataTags": null, + "z1D_StatusQuerySelection": null, + "z1D Current Database Status": null, + "z1D_TaskTableRefreshDone": null, + "z1D_DefaultCompanyAction": null, + "z1D_DefaultCompanyInteger": null, + "WO Type Field 10": null, + "WO Type Field 11": null, + "WO Type Field 12": null, + "WO Type Field 13": null, + "WO Type Field 14": null, + "WO Type Field 15": null, + "WO Type Field 16": null, + "WO Type Field 17": null, + "WO Type Field 18": null, + "WO Type Field 19": null, + "WO Type Field 20": null, + "WO Type Field 21": null, + "WO Type Field 22": null, + "WO Type Field 23": null, + "WO Type Field 24": null, + "WO Type Field 25": null, + "WO Type Field 26": null, + "WO Type Field 27": null, + "WO Type Field 28": null, + "WO Type Field 29": null, + "WO Type Field 30": null, + "WO Type Field 10 Label": ".", + "WO Type Field 11 Label": ".", + "WO Type Field 12 Label": ".", + "WO Type Field 13 Label": ".", + "WO Type Field 14 Label": ".", + "WO Type Field 15 Label": ".", + "WO Type Field 16 Label": ".", + "WO Type Field 17 Label": ".", + "WO Type Field 18 Label": ".", + "WO Type Field 19 Label": ".", + "WO Type Field 20 Label": ".", + "WO Type Field 21 Label": ".", + "WO Type Field 22 Label": ".", + "WO Type Field 23 Label": ".", + "WO Type Field 24 Label": ".", + "WO Type Field 25 Label": ".", + "WO Type Field 26 Label": ".", + "WO Type Field 27 Label": ".", + "WO Type Field 28 Label": ".", + "WO Type Field 29 Label": ".", + "WO Type Field 30 Label": ".", + "z1D_ExternalQual": null, + "z1D_remove_colcount": 0, + "z1D_ImportBypass": null, + "z1D_Int_ColCount": null, + "z1D_company": "Calbro Services", + "z1D_OldLocationCompanyGroupID": null, + "z1D_NewLocationCompanyGroupID": null, + "ASLOGID": null, + "Parent_Job_GUID": null, + "z1D_Company_Get": null, + "z1G_WOTaskDisplayOptionSettings": "Yes", + "z1D_ConfirmGroup": null, + "z1D_FLagOpenWindow": null, + "z1D template": null, + "z1D ExtQualification": null, + "Mark Records for Delete": null, + "ObsoleteDataDelete": null, + "WO Type Field 48": null, + "WO Type Field 49": null, + "WO Type Field 50": null, + "WO Type Field 51": null, + "WO Type Field 48 Label": ".", + "WO Type Field 49 Label": ".", + "WO Type Field 50 Label": ".", + "WO Type Field 51 Label": ".", + "z1D ValidateInfo": null, + "z1d_Search_Template_Name": null, + "Automation Status": null, + "z1D_FTS_ScanTime": -3600, + "zTmp_ExpCommonInstanceID": null, + "WO Type Field 1 Label": "Username", + "WO Type Field 2 Label": "Sharefolder Name", + "WO Type Field 3 Label": "Access Type", + "WO Type Field 4 Label": ".", + "WO Type Field 5 Label": ".", + "WO Type Field 6 Label": ".", + "WO Type Field 7 Label": ".", + "WO Type Field 8 Label": ".", + "WO Type Field 9 Label": ".", + "WO Type Field 1 Value": null, + "WO Type Field 2 Value": null, + "WO Type Field 3 Value": null, + "WO Type Field 4 Value": null, + "WO Type Field 5 Value": null, + "WO Type Field 6 Value": null, + "WO Type Field 7 Value": null, + "WO Type Field 8 Value": null, + "WO Type Field 9 Value": null, + "z1D Char09": null, + "z1D_Integer_2": null, + "Application GUID": null, + "Property Value": null, + "CI_ReconId": null, + "Summary": "New Share Folder Access", + "Location Company": "Calbro Services", + "Support Organization": "IT Support", + "Support Group Name": "Service Desk", + "Chg Location Address": null, + "z1D Char01": null, + "Categorization Tier 1": null, + "Categorization Tier 2": null, + "Categorization Tier 3": null, + "z1D Char02": null, + "z1D Char03": null, + "z1D Char04": null, + "z1D Action": null, + "z1D Integer01": null, + "Support Group ID": "SGP000000000011", + "Company": "Calbro Services", + "z1D Char05": null, + "z1D Char06": null, + "Add Request For:": "Organization", + "z1D Char07": null, + "z1D Char08": null, + "z1D Char29": null, + "z1D Char10": null, + "z1D Char11": null, + "z1D Char12": null, + "z1D Char13": null, + "z1D Char14": null, + "z1D Lastcount": null, + "z1D Char15": null, + "Work Order Type": "General", + "Company3": "Calbro Services", + "z1D Char16": null, + "CAB Manager ( Change Co-ord )": null, + "CAB Manager Login": null, + "z1D Char17": null, + "z1D Date03": null, + "z1D Date04": null, + "Author Group ID": null, + "z1D Char18": null, + "z1D Char19": null, + "z1D Char20": null, + "z1D Char21": null, + "z1D Char22": null, + "Product Cat Tier 1(2)": null, + "Product Cat Tier 2 (2)": null, + "Product Cat Tier 3 (2)": null, + "Authoring Group": null, + "Authoring Organization": null, + "Authoring Company": null, + "z1D Authoring Company": null, + "z1D Authoring Organization": null, + "z1D Authoring Group": null, + "z1D Char23": null, + "z1D Permission Group ID": null, + "z1D Permission Group List": null, + "z1D Char24": null, + "z1D Char25": null, + "Product Name (2)": null, + "Product Model/Version (2)": null, + "Manufacturer (2)": null, + "z1D IC Status": null, + "z1D Task Action": null, + "ASORG": "IT Support", + "ASCPY": "Calbro Services", + "ASGRP": "Service Desk", + "ASCHG": null, + "ASGRPID": "SGP000000000011", + "z1D Task Exist": null, + "z1D Task Status": null + }, + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:Template/000000000000003" + } + ] + } + } + ], + "_links": { + "next": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:Template?offset=2&limit=2" + } + ], + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:Template?limit=2" + } + ] + } +} \ No newline at end of file diff --git a/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_work_order_template_filter.json b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_work_order_template_filter.json new file mode 100644 index 000000000000..aed4cdf2f82c --- /dev/null +++ b/Packs/BmcITSM/Integrations/BmcITSM/test_data/list_work_order_template_filter.json @@ -0,0 +1,264 @@ +{ + "entries": [ + { + "values": { + "Request ID": "000000000000009", + "Submitter": "Arthur Agent", + "Submit Date": "2023-06-12T12:29:07.000+0000", + "Assigned To": null, + "Last Modified By": "Arthur Agent", + "Last Modified Date": "2023-06-12T12:29:07.000+0000", + "Status": "Enabled", + "Template Name": "UNIX User Password Reset", + "Notifier Listening": "Not Listening", + "Assignee Groups": "1000000001;", + "GUID": "IDGCWH5RDMNSBARWFDYBRWFDYBB8NV", + "Record ID": "AGGCWH5RDMNSBARWFEA9RWFEA9B90F", + "Vendor Assignee Groups": null, + "Vendor Assignee Groups_parent": null, + "Assignee Groups_parent": "", + "z1G_DefaultCompany": null, + "z1G_Global_AST_ProductionDataSetID": null, + "z1G_UnrestrictedAccessMember": null, + "z1G_TMSDirtyStructureFlag": null, + "Notes": "UNIX User Password Reset", + "zTmpAuditAction": null, + "zTmpAuditOldStatus": null, + "zTmpAuditWorkspace": null, + "zTmpNonAuditable": null, + "zTmpTableLoadedMask": null, + "zTmpRequestID": null, + "Change in Sequence": null, + "z1D_Integer": null, + "z1D_ChildSequenceChange": null, + "z1D_SelectedTaskId": null, + "z1D_Task Event Code": null, + "z1D_TaskSubtype": null, + "z1D_Task instance Id": null, + "z1D_Task Id": null, + "z1D_Process Id": null, + "z1D_Task Event Info 1": null, + "z1D_Task Event Info 2": null, + "z1D_Task Event Info 3": null, + "z1D_Task Event Info 4": null, + "z1D_Task Event Info 5": null, + "z1D_Task Event Info 6": null, + "z1D_NextSequence": null, + "z1D_SelectedTaskGroupId": null, + "z1D_TypeSelector": null, + "z1D_ChildTaskTG": null, + "zTmpInstanceNum": null, + "zTmpPredecessorID": null, + "zTmpSuccessorID": null, + "zTmpFlowID": null, + "zTmpStart": null, + "zTmp_SelectOne": null, + "Name": "UNIX User Password Reset", + "Category": null, + "z1D_TaskGroupType": null, + "z1D_Child Type": null, + "Product Categorization Tier 1": null, + "Product Categorization Tier 2": null, + "Product Categorization Tier 3": null, + "Site Group": null, + "Region": null, + "Business Service": null, + "Product Name": null, + "Site": null, + "z1D_Dirty Flag": null, + "z1D_DirtyFlagAssociations": null, + "Topic": null, + "MappedTemplateInstanceId": "IDGCWH5RDMNSBARWFDYBRWFDYBB8NV", + "MappedTemplate_Name": "UNIX User Password Reset", + "MappedTemplatedDescription": "UNIX User Password Reset", + "Used_by_SRMS": null, + "Assignment_Accelerator_Assignee": null, + "Assignment_Accelerator_Manager": null, + "DataTags": null, + "z1D_StatusQuerySelection": null, + "z1D Current Database Status": null, + "z1D_TaskTableRefreshDone": null, + "z1D_DefaultCompanyAction": null, + "z1D_DefaultCompanyInteger": null, + "WO Type Field 10": null, + "WO Type Field 11": null, + "WO Type Field 12": null, + "WO Type Field 13": null, + "WO Type Field 14": null, + "WO Type Field 15": null, + "WO Type Field 16": null, + "WO Type Field 17": null, + "WO Type Field 18": null, + "WO Type Field 19": null, + "WO Type Field 20": null, + "WO Type Field 21": null, + "WO Type Field 22": null, + "WO Type Field 23": null, + "WO Type Field 24": null, + "WO Type Field 25": null, + "WO Type Field 26": null, + "WO Type Field 27": null, + "WO Type Field 28": null, + "WO Type Field 29": null, + "WO Type Field 30": null, + "WO Type Field 10 Label": ".", + "WO Type Field 11 Label": ".", + "WO Type Field 12 Label": ".", + "WO Type Field 13 Label": ".", + "WO Type Field 14 Label": ".", + "WO Type Field 15 Label": ".", + "WO Type Field 16 Label": ".", + "WO Type Field 17 Label": ".", + "WO Type Field 18 Label": ".", + "WO Type Field 19 Label": ".", + "WO Type Field 20 Label": ".", + "WO Type Field 21 Label": ".", + "WO Type Field 22 Label": ".", + "WO Type Field 23 Label": ".", + "WO Type Field 24 Label": ".", + "WO Type Field 25 Label": ".", + "WO Type Field 26 Label": ".", + "WO Type Field 27 Label": ".", + "WO Type Field 28 Label": ".", + "WO Type Field 29 Label": ".", + "WO Type Field 30 Label": ".", + "z1D_ExternalQual": null, + "z1D_remove_colcount": 0, + "z1D_ImportBypass": null, + "z1D_Int_ColCount": null, + "z1D_company": "Calbro Services", + "z1D_OldLocationCompanyGroupID": null, + "z1D_NewLocationCompanyGroupID": null, + "ASLOGID": "Arthur Agent", + "Parent_Job_GUID": null, + "z1D_Company_Get": null, + "z1G_WOTaskDisplayOptionSettings": "Yes", + "z1D_ConfirmGroup": null, + "z1D_FLagOpenWindow": null, + "z1D template": null, + "z1D ExtQualification": null, + "Mark Records for Delete": null, + "ObsoleteDataDelete": null, + "WO Type Field 48": null, + "WO Type Field 49": null, + "WO Type Field 50": null, + "WO Type Field 51": null, + "WO Type Field 48 Label": ".", + "WO Type Field 49 Label": ".", + "WO Type Field 50 Label": ".", + "WO Type Field 51 Label": ".", + "z1D ValidateInfo": null, + "z1d_Search_Template_Name": null, + "Automation Status": "Manual", + "z1D_FTS_ScanTime": -3600, + "zTmp_ExpCommonInstanceID": null, + "WO Type Field 1 Label": "Username", + "WO Type Field 2 Label": "Email ID", + "WO Type Field 3 Label": ".", + "WO Type Field 4 Label": ".", + "WO Type Field 5 Label": ".", + "WO Type Field 6 Label": ".", + "WO Type Field 7 Label": ".", + "WO Type Field 8 Label": ".", + "WO Type Field 9 Label": ".", + "WO Type Field 1 Value": null, + "WO Type Field 2 Value": null, + "WO Type Field 3 Value": null, + "WO Type Field 4 Value": null, + "WO Type Field 5 Value": null, + "WO Type Field 6 Value": null, + "WO Type Field 7 Value": null, + "WO Type Field 8 Value": null, + "WO Type Field 9 Value": null, + "z1D Char09": null, + "z1D_Integer_2": null, + "Application GUID": null, + "Property Value": null, + "CI_ReconId": null, + "Summary": "UNIX User Password Reset", + "Location Company": "Calbro Services", + "Support Organization": "IT Support", + "Support Group Name": "Service Desk", + "Chg Location Address": null, + "z1D Char01": null, + "Categorization Tier 1": null, + "Categorization Tier 2": null, + "Categorization Tier 3": null, + "z1D Char02": null, + "z1D Char03": null, + "z1D Char04": null, + "z1D Action": null, + "z1D Integer01": null, + "Support Group ID": "SGP000000000011", + "Company": "Calbro Services", + "z1D Char05": null, + "z1D Char06": null, + "Add Request For:": "Organization", + "z1D Char07": null, + "z1D Char08": null, + "z1D Char29": null, + "z1D Char10": null, + "z1D Char11": null, + "z1D Char12": null, + "z1D Char13": null, + "z1D Char14": null, + "z1D Lastcount": null, + "z1D Char15": null, + "Work Order Type": "General", + "Company3": "Calbro Services", + "z1D Char16": null, + "CAB Manager ( Change Co-ord )": "Arthur Agent", + "CAB Manager Login": "Arthur Agent", + "z1D Char17": null, + "z1D Date03": null, + "z1D Date04": null, + "Author Group ID": null, + "z1D Char18": null, + "z1D Char19": null, + "z1D Char20": null, + "z1D Char21": null, + "z1D Char22": null, + "Product Cat Tier 1(2)": null, + "Product Cat Tier 2 (2)": null, + "Product Cat Tier 3 (2)": null, + "Authoring Group": null, + "Authoring Organization": null, + "Authoring Company": null, + "z1D Authoring Company": null, + "z1D Authoring Organization": null, + "z1D Authoring Group": null, + "z1D Char23": null, + "z1D Permission Group ID": null, + "z1D Permission Group List": null, + "z1D Char24": null, + "z1D Char25": null, + "Product Name (2)": null, + "Product Model/Version (2)": null, + "Manufacturer (2)": null, + "z1D IC Status": null, + "z1D Task Action": null, + "ASORG": "IT Support", + "ASCPY": "Calbro Services", + "ASGRP": "Service Desk", + "ASCHG": "Arthur Agent", + "ASGRPID": "SGP000000000011", + "z1D Task Exist": null, + "z1D Task Status": null + }, + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:Template/000000000000009" + } + ] + } + } + ], + "_links": { + "self": [ + { + "href": "https://isvpartners-dev-restapi.onbmc.com/api/arsys/v1/entry/WOI:Template?limit=2&q=%27Template%20Name%27%20like%20%22%25UNIX%25%22" + } + ] + } +} \ No newline at end of file diff --git a/Packs/BmcITSM/README.md b/Packs/BmcITSM/README.md index 0a23d47f4dcd..48597c9155f6 100644 --- a/Packs/BmcITSM/README.md +++ b/Packs/BmcITSM/README.md @@ -6,4 +6,4 @@ Cortex XSOAR interfaces with BMC Helix ITSM to help streamline security-related - Fetches BMC Helix ITSM tickets. - Mirrors incoming BMC Helix ITSM tickets in Cortex XSOAR. - Mirrors Cortex XSOAR tickets in BMC Helix ITSM. - - Supports service request, incident, change request, task, problem investigation and known error ticket types. + - Supports service request, incident, change request, task, problem investigation, known error and work order ticket types. diff --git a/Packs/BmcITSM/ReleaseNotes/1_0_22.md b/Packs/BmcITSM/ReleaseNotes/1_0_22.md new file mode 100644 index 000000000000..284ba37ae21b --- /dev/null +++ b/Packs/BmcITSM/ReleaseNotes/1_0_22.md @@ -0,0 +1,29 @@ + +#### Incident Fields + +- **BmcITSM Display ID** +- **BmcITSM Request ID** +- **BmcITSM Status Reason** +- **BmcITSM Submitter** +- **BmcITSM VIP Flag** + + +#### Incident Types + +- New: **BMC Work Order** + + +#### Integrations + +##### BMC Helix ITSM + +- Added the following commands: + - ***bmc-itsm-support-group-list*** + - ***bmc-itsm-work-order-template-list*** + - ***bmc-itsm-work-order-create*** + - ***bmc-itsm-work-order-update*** +- Added support for work order in the following commands: + - ***bmc-itsm-ticket-list*** + - ***bmc-itsm-ticket-delete*** + - ***bmc-itsm-task-create*** + diff --git a/Packs/BmcITSM/pack_metadata.json b/Packs/BmcITSM/pack_metadata.json index db114ce4f13c..75cb746144cf 100644 --- a/Packs/BmcITSM/pack_metadata.json +++ b/Packs/BmcITSM/pack_metadata.json @@ -1,8 +1,8 @@ { "name": "BMC Helix ITSM", - "description": "BMC Helix ITSM allows customers to manage service request, incident, change request, task, problem investigation and known error tickets.", + "description": "BMC Helix ITSM allows customers to manage service request, incident, change request, task, problem investigation, known error and work order tickets.", "support": "xsoar", - "currentVersion": "1.0.21", + "currentVersion": "1.0.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/package-lock.json b/package-lock.json index fd73e88d80d8..4381c1b1b658 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,1056 +1,1057 @@ { - "name": "content", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - } - }, - "@babel/core": { - "version": "7.12.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", - "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.7", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.9", - "@babel/types": "^7.12.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "requires": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "requires": { - "@babel/types": "^7.22.15" - } - }, - "@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==" - }, - "@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" - }, - "@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", - "requires": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" - } - }, - "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==" - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" - } - }, - "@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", - "debug": "^4.3.1", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", - "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@mdx-js/mdx": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", - "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", - "requires": { - "@babel/core": "7.12.9", - "@babel/plugin-syntax-jsx": "7.12.1", - "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@mdx-js/util": "1.6.22", - "babel-plugin-apply-mdx-type-prop": "1.6.22", - "babel-plugin-extract-import-names": "1.6.22", - "camelcase-css": "2.0.1", - "detab": "2.0.4", - "hast-util-raw": "6.0.1", - "lodash.uniq": "4.5.0", - "mdast-util-to-hast": "10.0.1", - "remark-footnotes": "2.0.0", - "remark-mdx": "1.6.22", - "remark-parse": "8.0.3", - "remark-squeeze-paragraphs": "4.0.0", - "style-to-object": "0.3.0", - "unified": "9.2.0", - "unist-builder": "2.0.3", - "unist-util-visit": "2.0.3" - } - }, - "@mdx-js/util": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", - "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==" - }, - "@types/hast": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.9.tgz", - "integrity": "sha512-pTHyNlaMD/oKJmS+ZZUyFUcsZeBZpC0lmGquw98CqRVNgAdJZJeD7GoeLiT6Xbx5rU9VCjSt0RwEvDgzh4obFw==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "requires": { - "@types/unist": "^2" - } - }, - "@types/parse5": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", - "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" - }, - "@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "babel-plugin-apply-mdx-type-prop": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz", - "integrity": "sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==", - "requires": { - "@babel/helper-plugin-utils": "7.10.4", - "@mdx-js/util": "1.6.22" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" + "name": "content", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "requires": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" } - } - }, - "babel-plugin-extract-import-names": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz", - "integrity": "sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==", - "requires": { - "@babel/helper-plugin-utils": "7.10.4" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" + }, + "@babel/core": { + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", + "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.9", + "@babel/types": "^7.12.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" } - } - }, - "bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" - }, - "camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" - }, - "ccount": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", - "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" - }, - "collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==" - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" - }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "detab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", - "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", - "requires": { - "repeat-string": "^1.5.4" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" - }, - "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "hast-to-hyperscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", - "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", - "requires": { - "@types/unist": "^2.0.3", - "comma-separated-tokens": "^1.0.0", - "property-information": "^5.3.0", - "space-separated-tokens": "^1.0.0", - "style-to-object": "^0.3.0", - "unist-util-is": "^4.0.0", - "web-namespaces": "^1.0.0" - } - }, - "hast-util-from-parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", - "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", - "requires": { - "@types/parse5": "^5.0.0", - "hastscript": "^6.0.0", - "property-information": "^5.0.0", - "vfile": "^4.0.0", - "vfile-location": "^3.2.0", - "web-namespaces": "^1.0.0" - } - }, - "hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" - }, - "hast-util-raw": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.0.1.tgz", - "integrity": "sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==", - "requires": { - "@types/hast": "^2.0.0", - "hast-util-from-parse5": "^6.0.0", - "hast-util-to-parse5": "^6.0.0", - "html-void-elements": "^1.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^3.0.0", - "vfile": "^4.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" - } - }, - "hast-util-to-parse5": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", - "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", - "requires": { - "hast-to-hyperscript": "^9.0.0", - "property-information": "^5.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" - } - }, - "hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", - "requires": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" - } - }, - "html-void-elements": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", - "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" - }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "requires": { - "hasown": "^2.0.0" - } - }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" - }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" - }, - "is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==" - }, - "is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==" - }, - "markdownlint": { - "version": "0.26.2", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", - "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", - "requires": { - "markdown-it": "13.0.1" - }, - "dependencies": { - "entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==" + }, + "@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "requires": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" + }, + "@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "requires": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "requires": { + "@babel/types": "^7.22.15" + } + }, + "@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==" + }, + "@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" + }, + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" + }, + "@babel/helpers": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", + "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", + "requires": { + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9" + } + }, + "@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", + "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==" + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", + "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.12.1" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", + "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/template": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", + "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", + "requires": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9" + } + }, + "@babel/traverse": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", + "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "requires": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.9", + "@babel/types": "^7.23.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", + "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "requires": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", + "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@mdx-js/mdx": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", + "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", + "requires": { + "@babel/core": "7.12.9", + "@babel/plugin-syntax-jsx": "7.12.1", + "@babel/plugin-syntax-object-rest-spread": "7.8.3", + "@mdx-js/util": "1.6.22", + "babel-plugin-apply-mdx-type-prop": "1.6.22", + "babel-plugin-extract-import-names": "1.6.22", + "camelcase-css": "2.0.1", + "detab": "2.0.4", + "hast-util-raw": "6.0.1", + "lodash.uniq": "4.5.0", + "mdast-util-to-hast": "10.0.1", + "remark-footnotes": "2.0.0", + "remark-mdx": "1.6.22", + "remark-parse": "8.0.3", + "remark-squeeze-paragraphs": "4.0.0", + "style-to-object": "0.3.0", + "unified": "9.2.0", + "unist-builder": "2.0.3", + "unist-util-visit": "2.0.3" + } + }, + "@mdx-js/util": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", + "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==" + }, + "@types/hast": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.9.tgz", + "integrity": "sha512-pTHyNlaMD/oKJmS+ZZUyFUcsZeBZpC0lmGquw98CqRVNgAdJZJeD7GoeLiT6Xbx5rU9VCjSt0RwEvDgzh4obFw==", + "requires": { + "@types/unist": "^2" + } + }, + "@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "requires": { + "@types/unist": "^2" + } + }, + "@types/parse5": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", + "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" + }, + "@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "babel-plugin-apply-mdx-type-prop": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz", + "integrity": "sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==", + "requires": { + "@babel/helper-plugin-utils": "7.10.4", + "@mdx-js/util": "1.6.22" }, - "linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", - "requires": { - "uc.micro": "^1.0.1" + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" } + } + }, + "babel-plugin-extract-import-names": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz", + "integrity": "sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==", + "requires": { + "@babel/helper-plugin-utils": "7.10.4" }, - "markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", - "requires": { - "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" } } - } - }, - "markdownlint-rule-helpers": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.2.tgz", - "integrity": "sha512-XaeoW2NYSlWxMCZM2B3H7YTG6nlaLfkEZWMBhr4hSPlq9MuY2sy83+Xr89jXOqZMZYjvi5nBCGoFh7hHoPKZmA==" - }, - "mdast-squeeze-paragraphs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", - "integrity": "sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==", - "requires": { - "unist-util-remove": "^2.0.0" - } - }, - "mdast-util-definitions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", - "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", - "requires": { - "unist-util-visit": "^2.0.0" - } - }, - "mdast-util-to-hast": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz", - "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==", - "requires": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "mdast-util-definitions": "^4.0.0", - "mdurl": "^1.0.0", - "unist-builder": "^2.0.0", - "unist-util-generated": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - } - }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "requires": { - "xtend": "^4.0.0" - } - }, - "remark-footnotes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-2.0.0.tgz", - "integrity": "sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==" - }, - "remark-mdx": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz", - "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==", - "requires": { - "@babel/core": "7.12.9", - "@babel/helper-plugin-utils": "7.10.4", - "@babel/plugin-proposal-object-rest-spread": "7.12.1", - "@babel/plugin-syntax-jsx": "7.12.1", - "@mdx-js/util": "1.6.22", - "is-alphabetical": "1.0.4", - "remark-parse": "8.0.3", - "unified": "9.2.0" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" + }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" + }, + "ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } + }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" + }, + "collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==" + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "comma-separated-tokens": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "detab": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", + "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", + "requires": { + "repeat-string": "^1.5.4" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "hast-to-hyperscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", + "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", + "requires": { + "@types/unist": "^2.0.3", + "comma-separated-tokens": "^1.0.0", + "property-information": "^5.3.0", + "space-separated-tokens": "^1.0.0", + "style-to-object": "^0.3.0", + "unist-util-is": "^4.0.0", + "web-namespaces": "^1.0.0" + } + }, + "hast-util-from-parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", + "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", + "requires": { + "@types/parse5": "^5.0.0", + "hastscript": "^6.0.0", + "property-information": "^5.0.0", + "vfile": "^4.0.0", + "vfile-location": "^3.2.0", + "web-namespaces": "^1.0.0" + } + }, + "hast-util-parse-selector": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" + }, + "hast-util-raw": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.0.1.tgz", + "integrity": "sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==", + "requires": { + "@types/hast": "^2.0.0", + "hast-util-from-parse5": "^6.0.0", + "hast-util-to-parse5": "^6.0.0", + "html-void-elements": "^1.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^3.0.0", + "vfile": "^4.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.0", + "zwitch": "^1.0.0" + } + }, + "hast-util-to-parse5": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", + "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", + "requires": { + "hast-to-hyperscript": "^9.0.0", + "property-information": "^5.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.0", + "zwitch": "^1.0.0" + } + }, + "hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "requires": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + } + }, + "html-void-elements": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", + "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "requires": { + "hasown": "^2.0.0" + } + }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" + }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + }, + "is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==" + }, + "is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==" + }, + "markdownlint": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.2.tgz", + "integrity": "sha512-2Am42YX2Ex5SQhRq35HxYWDfz1NLEOZWWN25nqd2h3AHRKsGRE+Qg1gt1++exW792eXTrR4jCNHfShfWk9Nz8w==", + "requires": { + "markdown-it": "13.0.1" + }, + "dependencies": { + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==" + }, + "linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "requires": { + "uc.micro": "^1.0.1" + } + }, + "markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "requires": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + } + } + }, + "markdownlint-rule-helpers": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.17.2.tgz", + "integrity": "sha512-XaeoW2NYSlWxMCZM2B3H7YTG6nlaLfkEZWMBhr4hSPlq9MuY2sy83+Xr89jXOqZMZYjvi5nBCGoFh7hHoPKZmA==" + }, + "mdast-squeeze-paragraphs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", + "integrity": "sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==", + "requires": { + "unist-util-remove": "^2.0.0" + } + }, + "mdast-util-definitions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", + "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", + "requires": { + "unist-util-visit": "^2.0.0" + } + }, + "mdast-util-to-hast": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz", + "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==", + "requires": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "mdast-util-definitions": "^4.0.0", + "mdurl": "^1.0.0", + "unist-builder": "^2.0.0", + "unist-util-generated": "^1.0.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "property-information": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "requires": { + "xtend": "^4.0.0" + } + }, + "remark-footnotes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-2.0.0.tgz", + "integrity": "sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==" + }, + "remark-mdx": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz", + "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==", + "requires": { + "@babel/core": "7.12.9", + "@babel/helper-plugin-utils": "7.10.4", + "@babel/plugin-proposal-object-rest-spread": "7.12.1", + "@babel/plugin-syntax-jsx": "7.12.1", + "@mdx-js/util": "1.6.22", + "is-alphabetical": "1.0.4", + "remark-parse": "8.0.3", + "unified": "9.2.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" + } + } + }, + "remark-parse": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", + "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", + "requires": { + "ccount": "^1.0.0", + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^2.0.0", + "vfile-location": "^3.0.0", + "xtend": "^4.0.1" + } + }, + "remark-squeeze-paragraphs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz", + "integrity": "sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==", + "requires": { + "mdast-squeeze-paragraphs": "^4.0.0" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + }, + "space-separated-tokens": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" + }, + "state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==" + }, + "style-to-object": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", + "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "requires": { + "inline-style-parser": "0.1.1" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==" + }, + "trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==" + }, + "trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, + "unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "requires": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "unified": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", + "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + } + }, + "unist-builder": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", + "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==" + }, + "unist-util-generated": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", + "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==" + }, + "unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" + }, + "unist-util-position": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==" + }, + "unist-util-remove": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-2.1.0.tgz", + "integrity": "sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==", + "requires": { + "unist-util-is": "^4.0.0" + } + }, + "unist-util-remove-position": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", + "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", + "requires": { + "unist-util-visit": "^2.0.0" + } + }, + "unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "requires": { + "@types/unist": "^2.0.2" + } + }, + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + } + }, + "vfile-location": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", + "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==" + }, + "vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + }, + "web-namespaces": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" } - }, - "remark-parse": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", - "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", - "requires": { - "ccount": "^1.0.0", - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^2.0.0", - "vfile-location": "^3.0.0", - "xtend": "^4.0.1" - } - }, - "remark-squeeze-paragraphs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz", - "integrity": "sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==", - "requires": { - "mdast-squeeze-paragraphs": "^4.0.0" - } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" - }, - "space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" - }, - "state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==" - }, - "style-to-object": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", - "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", - "requires": { - "inline-style-parser": "0.1.1" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==" - }, - "trim-trailing-lines": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", - "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==" - }, - "trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" - }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" - }, - "unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "requires": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "unified": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", - "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", - "requires": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - } - }, - "unist-builder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", - "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==" - }, - "unist-util-generated": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", - "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==" - }, - "unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" - }, - "unist-util-position": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==" - }, - "unist-util-remove": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-2.1.0.tgz", - "integrity": "sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==", - "requires": { - "unist-util-is": "^4.0.0" - } - }, - "unist-util-remove-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", - "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", - "requires": { - "unist-util-visit": "^2.0.0" - } - }, - "unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", - "requires": { - "@types/unist": "^2.0.2" - } - }, - "unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - } - }, - "unist-util-visit-parents": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" - } - }, - "vfile-location": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", - "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==" - }, - "vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" - } - }, - "web-namespaces": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", - "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" } } -} + \ No newline at end of file From f804cf48fba72b0ba3b56578580e064a34c1fc71 Mon Sep 17 00:00:00 2001 From: Adi Daud <46249224+adi88d@users.noreply.github.com> Date: Mon, 26 Feb 2024 15:41:08 +0200 Subject: [PATCH 093/272] add git add (#33105) --- .github/workflows/update-demisto-sdk-version.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/update-demisto-sdk-version.yml b/.github/workflows/update-demisto-sdk-version.yml index 8dfd8e845052..1d07304f6b29 100644 --- a/.github/workflows/update-demisto-sdk-version.yml +++ b/.github/workflows/update-demisto-sdk-version.yml @@ -54,6 +54,7 @@ jobs: run: | poetry add --group dev demisto-sdk@${{inputs.release_version}} poetry lock --no-update + git add . source .venv/bin/activate demisto-sdk pre-commit --mode=ci git add . From 3ce49327a273752c2bb915e3b12527a3d76259a7 Mon Sep 17 00:00:00 2001 From: Jacob Levy <129657918+jlevypaloalto@users.noreply.github.com> Date: Mon, 26 Feb 2024 16:10:15 +0200 Subject: [PATCH 094/272] Fix AWSRecreateSG EC2 breaking change bug (#32962) * fixed * remove print * update docker + RN * add BC warning * remove duplicate * fixed unit-tests * newline --- .../ReleaseNotes/1_1_16.md | 9 + .../Scripts/AWSRecreateSG/AWSRecreateSG.py | 37 +--- .../Scripts/AWSRecreateSG/AWSRecreateSG.yml | 2 +- .../AWSRecreateSG/AWSRecreateSG_test.py | 57 ++---- .../Scripts/AWSRecreateSG/test_data/sample.py | 163 +++++++----------- .../pack_metadata.json | 2 +- 6 files changed, 90 insertions(+), 180 deletions(-) create mode 100644 Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_16.md diff --git a/Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_16.md b/Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_16.md new file mode 100644 index 000000000000..627b0169c684 --- /dev/null +++ b/Packs/AWS-Enrichment-Remediation/ReleaseNotes/1_1_16.md @@ -0,0 +1,9 @@ + +#### Scripts + +##### AWSRecreateSG + +- Fixed an issue where the script failed with the latest version of the `AWS - EC2` integration. +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. + +**NOTE:** The `AWS - EC2` integration version must be greater than `1.4.0` for this script to run. diff --git a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.py b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.py index 2890f2ebae7a..c221214a2a79 100644 --- a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.py +++ b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.py @@ -1,7 +1,6 @@ import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 - from typing import Any import traceback from random import randint @@ -9,28 +8,6 @@ ROLE_SESSION_NAME = "xsoar-session" -def get_context_path(context: dict, path: str): - """Get a context output ignoring the DT suffix. - - Args: - context (dict): The context output with DT paths as keys. - path (str): The outputs prefix path without the DT transform under which the required data is held. - - Return: - (Any): The context data under the prefix. - - Example: - >>> output = demisto.executeCommand('aws-ec2-describe-addresses') - >>> output - {'Contents': {'path.to.data(val.Id && val.Id == obj.Id)': [1, 2, 3, 4]}} - >>> get_context_path(output, 'path.to.data') - [1, 2, 3, 4] - """ - return context.get( - next((key for key in context if key.partition('(')[0] == path), None) - ) - - def split_rule(rule: dict, port: int, protocol: str) -> list[dict]: """ If there are rules with ranges of ports, split them up @@ -93,7 +70,7 @@ def sg_fix(sg_info: list, port: int, protocol: str, assume_role: str, instance_t Returns: Dict: Dict of the new SG to be used """ - info = get_context_path(sg_info[0]['Contents'], 'AWS.EC2.SecurityGroups')[0] # type: ignore + info = dict_safe_get(sg_info, (0, 'Contents', 0)) recreate_list = [] # Keep track of change in SG or not. change = False @@ -109,13 +86,6 @@ def sg_fix(sg_info: list, port: int, protocol: str, assume_role: str, instance_t and rule['IpProtocol'] == protocol ): change = True - elif ( - rule["FromPort"] == port and port == rule["ToPort"] - and any(d["CidrIp"] == "0.0.0.0/0" for d in rule["IpRanges"]) - and rule["IpProtocol"] == protocol - ): - # If condition to check for Quad 0 in the rules list for matching port. - change = True elif ( rule['FromPort'] <= port and port <= rule['ToPort'] and any(d["CidrIp"] == "0.0.0.0/0" for d in rule["IpRanges"]) @@ -160,7 +130,7 @@ def sg_fix(sg_info: list, port: int, protocol: str, assume_role: str, instance_t new_sg = demisto.executeCommand("aws-ec2-create-security-group", cmd_args) if isError(new_sg): raise ValueError('Error on creating new security group') - new_id = new_sg[0]['Contents']['AWS.EC2.SecurityGroups']['GroupId'] + new_id = dict_safe_get(new_sg, (0, 'Contents', 'GroupId')) for item in recreate_list: cmd_args = {"groupId": new_id, "IpPermissionsFull": item, "using": instance_to_use} if assume_role: @@ -293,8 +263,7 @@ def instance_info(instance_id: str, public_ip: str, assume_role: str, region: st # Need a for loop in case multiple AWS-EC2 integrations are configured. match = False for instance in instance_info: - # Check if returned error, in the case of multiple integration instances only one should pass. - interfaces = get_context_path(instance.get('Contents'), 'AWS.EC2.Instances')[0].get('NetworkInterfaces') # type: ignore + interfaces = dict_safe_get(instance, ('Contents', 0, 'NetworkInterfaces')) if not isError(instance) and interfaces: mapping_dict = {} for interface in interfaces: diff --git a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.yml b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.yml index edccc4cc15b3..f9f15a05f2c9 100644 --- a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.yml +++ b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG.yml @@ -51,7 +51,7 @@ dependson: - AWS - EC2|||aws-ec2-authorize-security-group-egress-rule - AWS - EC2|||aws-ec2-revoke-security-group-ingress-rule - AWS - EC2|||aws-ec2-revoke-security-group-egress-rule -dockerimage: demisto/python3:3.10.13.84405 +dockerimage: demisto/python3:3.10.13.87159 enabled: true name: AWSRecreateSG runas: DBotWeakRole diff --git a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG_test.py b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG_test.py index e18a3162abc1..0597bb3ba21f 100644 --- a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG_test.py +++ b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/AWSRecreateSG_test.py @@ -72,9 +72,8 @@ def test_sg_fix(mocker): - Checks the output of the helper function with the expected output. """ from AWSRecreateSG import sg_fix - from test_data.sample import SG_INFO - new_sg = [{'Type': 1, 'Contents': {'AWS.EC2.SecurityGroups': {'GroupId': 'sg-00000000000000001'}}}] - mocker.patch.object(demisto, "executeCommand", return_value=new_sg) + from test_data.sample import SG_INFO, NEW_SG + mocker.patch.object(demisto, "executeCommand", return_value=NEW_SG) args = {"sg_info": SG_INFO, "port": 22, "protocol": "tcp", "assume_role": "test_role", "instance_to_use": "AWS - EC2", "region": "us-east-1"} result = sg_fix(**args) @@ -92,15 +91,13 @@ def test_determine_excessive_access(mocker): - Checks the output of the helper function with the expected output. """ from AWSRecreateSG import determine_excessive_access - from test_data.sample import SG_INFO - new_sg = [{'Type': 1, 'Contents': {'AWS.EC2.SecurityGroups': {'GroupId': 'sg-00000000000000001'}}}] + from test_data.sample import SG_INFO, NEW_SG - def executeCommand(name, args): - if name == "aws-ec2-describe-security-groups": - return SG_INFO - elif name == "aws-ec2-create-security-group": - return new_sg - return None + def executeCommand(name, *_): + return { + "aws-ec2-describe-security-groups": SG_INFO, + "aws-ec2-create-security-group": NEW_SG + }.get(name) mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand) args = {"int_sg_mapping": {'eni-00000000000000000': ['sg-00000000000000000']}, "port": 22, @@ -120,38 +117,18 @@ def test_aws_recreate_sg(mocker): - Checks the output of the function with the expected output. """ from AWSRecreateSG import aws_recreate_sg - from test_data.sample import SG_INFO, INSTANCE_INFO - new_sg = [{'Type': 1, 'Contents': {'AWS.EC2.SecurityGroups': {'GroupId': 'sg-00000000000000001'}}}] - - def executeCommand(name, args): - if name == "aws-ec2-describe-security-groups": - return SG_INFO - elif name == "aws-ec2-create-security-group": - return new_sg - elif name == "aws-ec2-describe-instances": - return INSTANCE_INFO - return None + from test_data.sample import SG_INFO, INSTANCE_INFO, NEW_SG - mocker.patch.object(demisto, "executeCommand", side_effect=executeCommand) + def execute_command(command, *_): + return { + "aws-ec2-describe-security-groups": SG_INFO, + "aws-ec2-create-security-group": NEW_SG, + "aws-ec2-describe-instances": INSTANCE_INFO + }.get(command) + + mocker.patch.object(demisto, "executeCommand", side_effect=execute_command) args = {"instance_id": "fake-instance-id", "public_ip": "1.1.1.1", "port": "22", "protocol": "tcp"} command_results = aws_recreate_sg(args) readable_output = command_results.readable_output correct_output = "For interface eni-00000000000000000: \r\nreplaced SG sg-00000000000000000 with sg-00000000000000001 \r\n" assert readable_output == correct_output - - -def test_get_context_path(): - """ - Given: - An output from demisto.excuteCommand('some-command')['Context'] - When: - Calling demisto.excuteCommand. - Then: - Get the context output. - """ - from AWSRecreateSG import get_context_path - - outputs = {'path.to.data(dt_path)': [1, 2, 3, 4]} - - assert get_context_path(outputs, 'path.to.data') == [1, 2, 3, 4] - assert get_context_path(outputs, 'wrong.path') is None diff --git a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/test_data/sample.py b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/test_data/sample.py index ccd2e3d7340b..acbaacb9ecd6 100644 --- a/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/test_data/sample.py +++ b/Packs/AWS-Enrichment-Remediation/Scripts/AWSRecreateSG/test_data/sample.py @@ -1,105 +1,61 @@ SG_INFO = [ { "Type": 1, - "Contents": { - "AWS.EC2.SecurityGroups(val.GroupId === obj.GroupId)": [ + "Contents": [ + { + "Description": "sldkjdlskfjs", + "GroupId": "sg-00000000000000001", + "GroupName": "demo-sg", + "IpPermissions": [ { - "Description": "sldkjdlskfjs", - "GroupId": "sg-00000000000000001", - "GroupName": "demo-sg", - "IpPermissions": [ + "FromPort": 0, + "IpProtocol": "tcp", + "IpRanges": [ { - "FromPort": 0, - "IpProtocol": "tcp", - "IpRanges": [ - { - "CidrIp": "0.0.0.0/0" - } - ], - "Ipv6Ranges": [], - "PrefixListIds": [], - "ToPort": 65535, - "UserIdGroupPairs": [] - }, + "CidrIp": "0.0.0.0/0" + } + ], + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 65535, + "UserIdGroupPairs": [] + }, + { + "FromPort": 22, + "IpProtocol": "tcp", + "IpRanges": [ { - "FromPort": 22, - "IpProtocol": "tcp", - "IpRanges": [ - { - "CidrIp": "0.0.0.0/0" - } - ], - "Ipv6Ranges": [], - "PrefixListIds": [], - "ToPort": 22, - "UserIdGroupPairs": [] + "CidrIp": "0.0.0.0/0" } ], - "IpPermissionsEgress": [ + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 22, + "UserIdGroupPairs": [] + } + ], + "IpPermissionsEgress": [ + { + "FromPort": 0, + "IpProtocol": "tcp", + "IpRanges": [ { - "FromPort": 0, - "IpProtocol": "tcp", - "IpRanges": [ - { - "CidrIp": "0.0.0.0/0" - } - ], - "Ipv6Ranges": [], - "PrefixListIds": [], - "ToPort": 65535, - "UserIdGroupPairs": [] + "CidrIp": "0.0.0.0/0" } ], - "OwnerId": "717007404259", - "Region": "us-east-1", - "VpcId": "vpc-061c242911e464170" + "Ipv6Ranges": [], + "PrefixListIds": [], + "ToPort": 65535, + "UserIdGroupPairs": [] } - ] - }, + ], + "OwnerId": "717007404259", + "Region": "us-east-1", + "VpcId": "vpc-061c242911e464170" + } + ], "HumanReadable": "### AWS EC2 SecurityGroups\n|Description|GroupId|GroupName|OwnerId|Region|VpcId|\n|---|---|---|---|---|---|\n| sldkjdlskfjs | sg-0408c2745d3d13b15 | demo-sg | 717007404259 | us-east-1 | vpc-061c242911e464170 |\n", "ImportantEntryContext": "None", - "EntryContext": { - "AWS.EC2.SecurityGroups(val.GroupId === obj.GroupId)": [ - { - "Description": "sldkjdlskfjs", - "GroupId": "sg-0408c2745d3d13b15", - "GroupName": "demo-sg", - "IpPermissions": [ - { - "FromPort": 0, - "IpProtocol": "tcp", - "IpRanges": [ - { - "CidrIp": "0.0.0.0/0" - } - ], - "Ipv6Ranges": "None", - "PrefixListIds": "None", - "ToPort": 65535, - "UserIdGroupPairs": "None" - } - ], - "IpPermissionsEgress": [ - { - "FromPort": 0, - "IpProtocol": "tcp", - "IpRanges": [ - { - "CidrIp": "0.0.0.0/0" - } - ], - "Ipv6Ranges": "None", - "PrefixListIds": "None", - "ToPort": 65535, - "UserIdGroupPairs": "None" - } - ], - "OwnerId": "717007404259", - "Region": "us-east-1", - "VpcId": "vpc-061c242911e464170" - } - ] - } } ] INSTANCE_INFO = [ @@ -108,25 +64,24 @@ "instance": "AWS - EC2" }, "Type": 1, - "Contents": { - "AWS.EC2.Instances(val.InstanceId === obj.InstanceId)": [ + "Contents": [ + { + "NetworkInterfaces": [ { - "NetworkInterfaces": [ + "Association": { + "PublicIp": "1.1.1.1" + }, + "Groups": [ { - "Association": { - "PublicIp": "1.1.1.1" - }, - "Groups": [ - { - "GroupId": "sg-00000000000000000", - "GroupName": "sg-name" - } - ], - "NetworkInterfaceId": "eni-00000000000000000" + "GroupId": "sg-00000000000000000", + "GroupName": "sg-name" } - ] + ], + "NetworkInterfaceId": "eni-00000000000000000" } - ] - } + ] + } + ] } ] +NEW_SG = [{'Type': 1, 'Contents': {'GroupId': 'sg-00000000000000001'}}] diff --git a/Packs/AWS-Enrichment-Remediation/pack_metadata.json b/Packs/AWS-Enrichment-Remediation/pack_metadata.json index 02e202cd9549..dafe86614af4 100644 --- a/Packs/AWS-Enrichment-Remediation/pack_metadata.json +++ b/Packs/AWS-Enrichment-Remediation/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS Enrichment and Remediation", "description": "Playbooks using multiple AWS content packs for enrichment and remediation purposes", "support": "xsoar", - "currentVersion": "1.1.15", + "currentVersion": "1.1.16", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 61b2d16c7413d0303132ccf5fc5bc45cbe7dec18 Mon Sep 17 00:00:00 2001 From: rshunim <102469772+rshunim@users.noreply.github.com> Date: Mon, 26 Feb 2024 16:55:58 +0200 Subject: [PATCH 095/272] Add Teradata to GenericSQL integration (#29352) * works with simple select query * add print for showing the table * revert self.port * Update Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.py Co-authored-by: dorschw <81086590+dorschw@users.noreply.github.com> * add support for ldap * add comment * Update Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.py Co-authored-by: dorschw <81086590+dorschw@users.noreply.github.com> * add pre_process_result_query function * pre-commit * typing * remove print and use devdocker * extract the code to external method and add UT for testing it * add limit and fix dialect * pre commit * converting b'' and datetime objects to readable ones for Teradata too * add UT for default ports * resolve conflicts * RN * add known_words * RN * revert changes * update UT, use constant * Update docker version * slight improvements * change error message * rename param * rename `is_ldap` to `use_ldap` * fix UT * naming * autopep8, type fix * bump * allow use pool with Teradata * CR * last comment --------- Co-authored-by: dorschw <81086590+dorschw@users.noreply.github.com> --- Packs/GenericSQL/.pack-ignore | 4 +- .../Integrations/GenericSQL/GenericSQL.py | 110 +++++++++++++----- .../Integrations/GenericSQL/GenericSQL.yml | 11 +- .../GenericSQL/GenericSQL_test.py | 44 ++++++- Packs/GenericSQL/ReleaseNotes/1_2_0.md | 5 + Packs/GenericSQL/pack_metadata.json | 2 +- 6 files changed, 140 insertions(+), 36 deletions(-) create mode 100644 Packs/GenericSQL/ReleaseNotes/1_2_0.md diff --git a/Packs/GenericSQL/.pack-ignore b/Packs/GenericSQL/.pack-ignore index f0a5d80d4d09..85805df072c8 100644 --- a/Packs/GenericSQL/.pack-ignore +++ b/Packs/GenericSQL/.pack-ignore @@ -5,4 +5,6 @@ ignore=RM106 MS ODBC Postgres -TLS \ No newline at end of file +TLS +Teradata +DB \ No newline at end of file diff --git a/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.py b/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.py index d5e3d44f37e3..06a49bf699e7 100644 --- a/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.py +++ b/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.py @@ -13,6 +13,7 @@ from urllib.parse import parse_qsl import dateparser +TERADATA = "Teradata" ORACLE = "Oracle" POSTGRES_SQL = "PostgreSQL" MY_SQL = "MySQL" @@ -26,7 +27,6 @@ except Exception: # noqa: S110 pass - # In order to use and convert from pymysql to MySQL this line is necessary pymysql.install_as_MySQLdb() @@ -44,7 +44,9 @@ class Client: def __init__(self, dialect: str, host: str, username: str, password: str, port: str, database: str, connect_parameters: str, ssl_connect: bool, use_pool=False, verify_certificate=True, - pool_ttl=DEFAULT_POOL_TTL): + pool_ttl: int = DEFAULT_POOL_TTL, use_ldap: bool = False): + if use_ldap and dialect != TERADATA: + raise ValueError(f"The LDAP parameter is only supported with {TERADATA}") self.dialect = dialect self.host = host self.username = username @@ -55,6 +57,7 @@ def __init__(self, dialect: str, host: str, username: str, password: str, port: self.ssl_connect = ssl_connect self.use_pool = use_pool self.pool_ttl = pool_ttl + self.use_ldap = use_ldap self.connection = self._create_engine_and_connect() @staticmethod @@ -115,6 +118,31 @@ def _get_global_cache(self) -> dict: setattr(sqlalchemy, GLOBAL_CACHE_ATTR, cache) return cache + def _generate_db_url(self, module): + """ + This method generates the db url object for creating the engine later. + Args: + module: + The appropriate module according to the db. + Returns: + The URL object, in case of Teradata is an url string. + """ + + # Teradata has a unique connection, unlike the others with URL object + if self.dialect == TERADATA: + if self.use_ldap: + return f'teradatasql://{self.username}:{self.password}@{self.host}:{self.port}/?logmech=LDAP' + else: + return f'teradatasql://{self.host}:{self.port}/?user={self.username}&password={self.password}' + + return URL(drivername=module, + username=self.username, + password=self.password, + host=self.host, + port=arg_to_number(self.port), + database=self.dbname, + query=self.connect_parameters) + def _create_engine_and_connect(self) -> sqlalchemy.engine.base.Connection: """ Creating and engine according to the instance preferences and connecting @@ -122,19 +150,14 @@ def _create_engine_and_connect(self) -> sqlalchemy.engine.base.Connection: """ ssl_connection = {} module = self._convert_dialect_to_module(self.dialect) - db_url = URL(drivername=module, - username=self.username, - password=self.password, - host=self.host, - port=arg_to_number(self.port), - database=self.dbname, - query=self.connect_parameters) + db_url = self._generate_db_url(module) + if self.ssl_connect: if self.dialect == POSTGRES_SQL: ssl_connection = {'sslmode': 'require'} else: ssl_connection = {'ssl': {'ssl-mode': 'preferred'}} # type: ignore[dict-item] - engine: sqlalchemy.engine.Engine = None + if self.use_pool: if 'expiringdict' not in sys.modules: raise ValueError('Usage of connection pool is not support in this docker image') @@ -144,6 +167,7 @@ def _create_engine_and_connect(self) -> sqlalchemy.engine.base.Connection: if engine is None: # (first time or expired) need to initialize engine = sqlalchemy.create_engine(db_url, connect_args=ssl_connection) cache[cache_key] = engine + else: demisto.debug('Initializing engine with no pool (NullPool)') engine = sqlalchemy.create_engine(db_url, connect_args=ssl_connection, @@ -174,26 +198,29 @@ def sql_query_execute_request(self, sql_query: str, bind_vars: Any, fetch_limit= headers = [] if results: - # if the table isn't empty - headers = list(results[0].keys() or '') - + # Teradata's response structure differs from those of other databases + if self.dialect == TERADATA: + headers = list(result.keys()) + else: + headers = list(results[0].keys() or '') return results, headers def generate_default_port_by_dialect(dialect: str) -> str | None: """ - In case no port was chosen, a default port will be chosen according to the SQL db type. Only return a port for - Microsoft SQL Server and ODBC Driver 18 for SQL Server where it seems to be required. - For the other drivers a None port is supported + In case no port was chosen, a default port will be chosen according to the SQL db type. + Returns a port for drivers that seem to require it. For other drivers, a None port is supported. :param dialect: sql db type :return: default port needed for connection """ - if dialect in {'Microsoft SQL Server', 'ODBC Driver 18 for SQL Server'}: - return "1433" - return None + return { + "Microsoft SQL Server": "1433", + "ODBC Driver 18 for SQL Server": "1433", + TERADATA: "1025", + }.get(dialect) -def generate_variable_names_and_mapping(bind_variables_values_list: list, query: str, dialect: str) ->\ +def generate_variable_names_and_mapping(bind_variables_values_list: list, query: str, dialect: str) -> \ tuple[dict[str, Any], str | Any]: """ In case of passing just bind_variables_values, since it's no longer supported in SQL Alchemy v2., @@ -219,8 +246,8 @@ def generate_variable_names_and_mapping(bind_variables_values_list: list, query: bind_variables_names_list = [] for i in range(len(re.findall(char_to_count, query))): - query = query.replace(char_to_replace, f":bind_variable_{i+1}", 1) - bind_variables_names_list.append(f"bind_variable_{i+1}") + query = query.replace(char_to_replace, f":bind_variable_{i + 1}", 1) + bind_variables_names_list.append(f"bind_variable_{i + 1}") return dict(zip(bind_variables_names_list, bind_variables_values_list)), query @@ -243,7 +270,10 @@ def generate_bind_vars(bind_variables_names: str, bind_variables_values: str, qu elif len(bind_variables_names_list) == len(bind_variables_values_list): return dict(zip(bind_variables_names_list, bind_variables_values_list)), query else: - raise Exception("The bind variables lists are not is the same length") + raise Exception( + "Bind variables length must match the variable count." + f"Got {len(bind_variables_names_list)} variables and {len(bind_variables_values_list)} values" + ) def test_module(client: Client, *_) -> tuple[str, dict[Any, Any], list[Any]]: @@ -267,7 +297,7 @@ def test_module(client: Client, *_) -> tuple[str, dict[Any, Any], list[Any]]: if params.get('fetch_parameters') == 'ID and timestamp' and not (params.get('column_name') and params.get('id_column')): msg += 'Missing Fetch Column or ID Column name (when ID and timestamp are chosen,' \ - ' fill in both). ' + ' fill in both). ' if params.get('fetch_parameters') in ['Unique ascending', 'Unique timestamp']: if not params.get('column_name'): @@ -317,6 +347,23 @@ def test_module(client: Client, *_) -> tuple[str, dict[Any, Any], list[Any]]: return msg if msg else 'ok', {}, [] +def result_to_list_of_dicts(client: Client, result: list[dict], headers: list[str]) -> list[dict]: + """ + This function pre-processes the query's result to a list of dictionaries. + """ + if client.dialect == TERADATA: + # binding the headers with the columns + converted_table = [dict(zip(headers, row)) for row in result] + else: + # converting a sqlalchemy object to a table + converted_table = [dict(row) for row in result] + + # converting b'' and datetime objects to readable ones + table = [{str(key): str(value) for key, value in dictionary.items()} for dictionary in converted_table] + + return table + + def sql_query_execute(client: Client, args: dict, *_) -> tuple[str, dict[str, Any], list[dict[str, Any]]]: """ Executes the sql query with the connection that was configured in the client @@ -332,14 +379,15 @@ def sql_query_execute(client: Client, args: dict, *_) -> tuple[str, dict[str, An bind_variables_values = args.get('bind_variables_values', "") bind_variables, sql_query = generate_bind_vars(bind_variables_names, bind_variables_values, sql_query, client.dialect) - result, headers = client.sql_query_execute_request(sql_query, bind_variables) - result = convert_sqlalchemy_to_readable_table(result) - result = result[skip:skip + limit] + result, headers = client.sql_query_execute_request(sql_query, bind_variables, limit) - human_readable = tableToMarkdown(name="Query result", t=result, headers=headers, removeNull=True) + table = result_to_list_of_dicts(client, result, headers) + table = table[skip:skip + limit] + human_readable = tableToMarkdown(name="Query result:", t=table, headers=headers, + removeNull=True) context = { - "Result": result, + "Result": table, "Headers": headers, "Query": sql_query, "InstanceName": f"{client.dialect}_{client.dbname}", @@ -577,15 +625,17 @@ def main(): ssl_connect = params.get('ssl_connect') connect_parameters = params.get('connect_parameters') use_pool = params.get('use_pool', False) + use_ldap = params.get('use_ldap', False) verify_certificate: bool = not params.get('insecure', False) pool_ttl = int(params.get('pool_ttl') or DEFAULT_POOL_TTL) if pool_ttl <= 0: pool_ttl = DEFAULT_POOL_TTL command = demisto.command() + LOG(f'Command being called in SQL is: {command}') client = Client(dialect=dialect, host=host, username=user, password=password, port=port, database=database, connect_parameters=connect_parameters, ssl_connect=ssl_connect, use_pool=use_pool, verify_certificate=verify_certificate, - pool_ttl=pool_ttl) + pool_ttl=pool_ttl, use_ldap=use_ldap) commands: dict[str, Callable[[Client, dict[str, str], str], tuple[str, dict[Any, Any], list[Any]]]] = { 'test-module': test_module, 'query': sql_query_execute, diff --git a/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml b/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml index 4ddc1ba476d1..485f77769d07 100644 --- a/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml +++ b/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL.yml @@ -12,6 +12,7 @@ configuration: - Microsoft SQL Server - Microsoft SQL Server - MS ODBC Driver - Oracle + - Teradata required: true type: 15 - display: Database host @@ -88,12 +89,16 @@ configuration: name: insecure type: 8 required: false +- display: Use LDAP (Teradata only) + name: use_ldap + type: 8 + required: false - display: Connection Pool Time to Live (seconds) - additionalinfo: After this time the connection pool will be refreshed - defaultvalue: 600 name: pool_ttl type: 0 required: false + additionalinfo: After this time the connection pool will be refreshed + defaultvalue: 600 - display: Incident type name: incidentType type: 13 @@ -157,7 +162,7 @@ script: - description: 'A comma-separated list of value, for example: 7,"foo",3.' isArray: true name: bind_variables_values - description: Running a sql query + description: Running a sql query. name: sql-command dockerimage: demisto/genericsql:1.1.0.87817 isfetch: true diff --git a/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL_test.py b/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL_test.py index 5007b4f2dfd1..1d2a496a6be0 100644 --- a/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL_test.py +++ b/Packs/GenericSQL/Integrations/GenericSQL/GenericSQL_test.py @@ -239,6 +239,46 @@ def test_sql_queries(command, args, response, expected_result, header, mocker): assert expected_result == result[1] # entry context is found in the 2nd place in the result of the command +@pytest.mark.parametrize('use_ldap, expected_url', [ + pytest.param(True, "teradatasql://username:password@host:/?logmech=LDAP", id="LDAP"), + pytest.param(False, "teradatasql://host:/?user=username&password=password", id="Username & Password"), +]) +def test_teradata_connection(mocker, use_ldap: bool, expected_url: str): + """ + Given + - All required arguments for the client + - The use_ldap parameter + When + - Executing _create_engine_url_for_teradata client's method + Then + - Ensure the engine url is generated correctly according to use_ldap + """ + + mock_create_engine = mocker.patch.object(sqlalchemy, 'create_engine') + Client(dialect='Teradata', host='host', username='username', password='password', port='', connect_parameters='', + database='', ssl_connect=False, use_ldap=use_ldap) + assert mock_create_engine.mock_calls[0][1][0] == expected_url + + +@pytest.mark.parametrize('dialect, expected_port', [ + ("Microsoft SQL Server", "1433"), + ("ODBC Driver 18 for SQL Server", "1433"), + ("Teradata", "1025"), + ("DB_NOT_EXIST", None), +]) +def test_generate_default_port_by_dialect(dialect: str, expected_port: str): + """ + Given + - a dialect (DB) + When + - Executing generate_default_port_by_dialect() function + Then + - Ensure the right port is generated or None in case of DB not found + """ + + assert generate_default_port_by_dialect(dialect) == expected_port + + def test_sql_queries_with_empty_table(mocker): """Unit test Given @@ -272,7 +312,9 @@ def test_mysql_integration(): if not host: pytest.skip('Skipping mysql integration test as MYSQL_HOST is not set') dialect = 'MySQL' - client = Client(dialect, host, 'root', 'password', generate_default_port_by_dialect(dialect), 'mysql', "", False, True) + port = generate_default_port_by_dialect(dialect) + assert port is not None + client = Client(dialect, host, 'root', 'password', port, 'mysql', "", False, True) res = client.sql_query_execute_request('show processlist', {}) assert len(res) >= 1 diff --git a/Packs/GenericSQL/ReleaseNotes/1_2_0.md b/Packs/GenericSQL/ReleaseNotes/1_2_0.md new file mode 100644 index 000000000000..e0aeda558c7e --- /dev/null +++ b/Packs/GenericSQL/ReleaseNotes/1_2_0.md @@ -0,0 +1,5 @@ +#### Integrations +##### Generic SQL + +- Added support for Teradata DB. +- Updated the Docker image to: *demisto/genericsql:1.1.0.87817*. \ No newline at end of file diff --git a/Packs/GenericSQL/pack_metadata.json b/Packs/GenericSQL/pack_metadata.json index 21b7cee151d0..48a531778ade 100644 --- a/Packs/GenericSQL/pack_metadata.json +++ b/Packs/GenericSQL/pack_metadata.json @@ -3,7 +3,7 @@ "description": "Connect and execute sql queries in 4 Databases: MySQL, PostgreSQL, Microsoft SQL Server and Oracle", "support": "xsoar", "serverMinVersion": "5.0.0", - "currentVersion": "1.1.7", + "currentVersion": "1.2.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 8726ac434af8f3c8a27e8bce60ea6cd80f242872 Mon Sep 17 00:00:00 2001 From: yasta5 <112320333+yasta5@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:11:37 +0200 Subject: [PATCH 096/272] Refactor product parsing rule ms graph (#33049) * Change the product value of in the parsing rule. * Added release note. * Bump pack from version MicrosoftGraphSecurity to 2.2.10. --------- Co-authored-by: Content Bot --- .../MicrosoftGraphSecurity/MicrosoftGraphSecurity.xif | 2 +- Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_10.md | 3 +++ Packs/MicrosoftGraphSecurity/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_10.md diff --git a/Packs/MicrosoftGraphSecurity/ParsingRules/MicrosoftGraphSecurity/MicrosoftGraphSecurity.xif b/Packs/MicrosoftGraphSecurity/ParsingRules/MicrosoftGraphSecurity/MicrosoftGraphSecurity.xif index 4a7bbbc4798b..ab106c9d12fe 100644 --- a/Packs/MicrosoftGraphSecurity/ParsingRules/MicrosoftGraphSecurity/MicrosoftGraphSecurity.xif +++ b/Packs/MicrosoftGraphSecurity/ParsingRules/MicrosoftGraphSecurity/MicrosoftGraphSecurity.xif @@ -1,3 +1,3 @@ -[INGEST:vendor="msft", product="graph_security_alerts", target_dataset="msft_graph_security_alerts_raw", no_hit=keep] +[INGEST:vendor="msft", product="Graph Security Alerts", target_dataset="msft_graph_security_alerts_raw", no_hit=keep] filter to_string(createdDateTime) ~= "\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z" | alter _time = parse_timestamp("%Y-%m-%dT%H:%M:%E*SZ", to_string(createdDateTime)); \ No newline at end of file diff --git a/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_10.md b/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_10.md new file mode 100644 index 000000000000..946bd107aae0 --- /dev/null +++ b/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_10.md @@ -0,0 +1,3 @@ +#### Parsing Rules +##### Microsoft Graph Security Parsing Rules +Fixed an issue with the product name. \ No newline at end of file diff --git a/Packs/MicrosoftGraphSecurity/pack_metadata.json b/Packs/MicrosoftGraphSecurity/pack_metadata.json index 4d5be5550c33..3075994a1060 100644 --- a/Packs/MicrosoftGraphSecurity/pack_metadata.json +++ b/Packs/MicrosoftGraphSecurity/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Security", "description": "Unified gateway to security insights - all from a unified Microsoft Graph\n Security API.", "support": "xsoar", - "currentVersion": "2.2.9", + "currentVersion": "2.2.10", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 38a7e813d16d2b3517a92a9feb612447f1316b5e Mon Sep 17 00:00:00 2001 From: Darya Koval <72339940+daryakoval@users.noreply.github.com> Date: Mon, 26 Feb 2024 21:03:37 +0200 Subject: [PATCH 097/272] Extract indicators hyperlinks (#33073) * initial script * aded docker image * stated tests * save new tests and fixes * save new tests and fixes * white secret; rn * readme * rn * randomness in the test fix * Apply suggestions from code review Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> * outputs key field array * new docker image * . --------- Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> --- Packs/CommonScripts/.secrets-ignore | 3 +- Packs/CommonScripts/ReleaseNotes/1_14_2.md | 6 ++ .../ExtractHyperlinksFromOfficeFiles.py | 100 ++++++++++++++++++ .../ExtractHyperlinksFromOfficeFiles.yml | 22 ++++ .../ExtractHyperlinksFromOfficeFiles_test.py | 38 +++++++ .../README.md | 50 +++++++++ .../test_data/d1.docx | Bin 0 -> 27905 bytes .../test_data/d2.docx | Bin 0 -> 27729 bytes .../test_data/e1.xlsx | Bin 0 -> 31854 bytes .../test_data/e2.xlsx | Bin 0 -> 16370 bytes .../test_data/e3.xlsx | Bin 0 -> 16511 bytes .../test_data/p1.pptx | Bin 0 -> 42561 bytes .../test_data/p2.pptx | Bin 0 -> 42406 bytes Packs/CommonScripts/pack_metadata.json | 2 +- 14 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 Packs/CommonScripts/ReleaseNotes/1_14_2.md create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles.py create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles.yml create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles_test.py create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/README.md create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/d1.docx create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/d2.docx create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/e1.xlsx create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/e2.xlsx create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/e3.xlsx create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/p1.pptx create mode 100644 Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/p2.pptx diff --git a/Packs/CommonScripts/.secrets-ignore b/Packs/CommonScripts/.secrets-ignore index 467ec6b009b2..465f649213da 100644 --- a/Packs/CommonScripts/.secrets-ignore +++ b/Packs/CommonScripts/.secrets-ignore @@ -122,4 +122,5 @@ multipart/signed http://itunes.apple.com https://www.linkedin.com http://en.m.wikipedia.org -https://xsoar.pan.dev/docs/concepts/demisto-sdk#secrets \ No newline at end of file +https://xsoar.pan.dev/docs/concepts/demisto-sdk#secrets +http://www.yahoo.de diff --git a/Packs/CommonScripts/ReleaseNotes/1_14_2.md b/Packs/CommonScripts/ReleaseNotes/1_14_2.md new file mode 100644 index 000000000000..7d3e5cac3ffc --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_14_2.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### New: ExtractHyperlinksFromOfficeFiles + +- New: Extract hyperlinks from office files. Supported file types are: xlsx, docx, pptx. (Available from Cortex XSOAR 5.5.0). diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles.py b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles.py new file mode 100644 index 000000000000..8786248758d3 --- /dev/null +++ b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles.py @@ -0,0 +1,100 @@ +import demistomock as demisto # noqa: F401 +from CommonServerPython import * # noqa: F401 +import openpyxl +from docx import Document +from pptx import Presentation +import zipfile +import pandas as pd + + +def extract_hyperlinks_from_xlsx(file_path: str) -> Set: + with zipfile.ZipFile(file_path, "r") as zf: + xmls = [zf.read(fn) for fn in zf.infolist() + if fn.filename.startswith("xl/drawings/_rels/")] + + urls = set() + + for xml_data in xmls: + df = pd.read_xml(xml_data) + + if "TargetMode" in df.columns: + filtered_df = df.loc[df["TargetMode"].eq("External"), "Target"] + urls |= set(filtered_df) + + wb = openpyxl.load_workbook(file_path) + for sheet in wb: + for row in sheet.iter_rows(): + for cell in row: + if cell.hyperlink: + urls.add(cell.hyperlink.target) + + return urls + + +def extract_hyperlinks_from_docx(file_path: str) -> Set: + doc = Document(file_path) + links = set() + for para in doc.paragraphs: + for hyper in para.hyperlinks: + if hyper.address: + links.add(hyper.address) + return links + + +def extract_hyperlinks_from_pptx(file_path: str) -> Set: + prs = Presentation(file_path) + links = set() + for slide in prs.slides: + for shape in slide.shapes: + if shape.has_text_frame: + for paragraph in shape.text_frame.paragraphs: + for run in paragraph.runs: + if run.hyperlink and run.hyperlink.address: + links.add(run.hyperlink.address) + if shape.click_action and shape.click_action.hyperlink.address: + links.add(shape.click_action.hyperlink.address) + + return links + + +def extract_hyperlink_by_file_type(file_name: str, file_path: str) -> CommandResults: + if file_name.endswith('.xlsx'): + result = extract_hyperlinks_from_xlsx(file_path) + elif file_name.endswith('.docx'): + result = extract_hyperlinks_from_docx(file_path) + elif file_name.endswith('.pptx'): + result = extract_hyperlinks_from_pptx(file_path) + else: + raise ValueError("Unsupported file type. Supported types are: 'xlsx, docx, pptx'") + if result: + urls_str = "\n".join(result) + hr = f'### Extracted Hyperlinks\n\n{urls_str}' + else: + hr = '**No hyperlinks.**' + + output = [{'URL': url, 'FileName': file_name} for url in result] + return CommandResults( + outputs=output, + outputs_prefix='ExtractedHyperLink', + outputs_key_field=['URL', 'FileName'], + readable_output=hr, + raw_response=list(result) + ) + + +def main(): # pragma: no cover + try: + entry_id = demisto.args().get("entry_id") + file_result = demisto.getFilePath(entry_id) + if not file_result: + raise ValueError(f"Couldn't find entry id: {entry_id}") + file_name = file_result.get('name') + file_path = file_result.get('path') + os.rename(f'./{file_path}', file_name) + return_results(extract_hyperlink_by_file_type(file_name=file_name, file_path=os.path.realpath(file_name))) + except Exception as ex: + return_error(f'Failed to execute ExtractHyperlinksFromOfficeFiles. Error: {str(ex)}') + + +if __name__ in ('__main__', '__builtin__', 'builtins'): + main() diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles.yml b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles.yml new file mode 100644 index 000000000000..2842d24fe96a --- /dev/null +++ b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles.yml @@ -0,0 +1,22 @@ +args: +- description: 'The entry id of the file to extract hyperlinks from.' + name: entry_id + required: true +comment: 'Extracts hyperlinks from office files. Supported file types are: xlsx, docx, pptx.' +commonfields: + id: ExtractHyperlinksFromOfficeFiles + version: -1 +name: ExtractHyperlinksFromOfficeFiles +outputs: +- contextPath: ExtractedHyperLink.URL + description: The URL of the extracted hyperlink. + type: String +- contextPath: ExtractedHyperLink.FileName + description: The office file from which the hyperlinks are extracted. + type: String +script: '-' +timeout: '0' +type: python +subtype: python3 +dockerimage: demisto/office-utils:2.0.0.88298 +fromversion: 5.5.0 diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles_test.py b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles_test.py new file mode 100644 index 000000000000..7f26494c3a78 --- /dev/null +++ b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/ExtractHyperlinksFromOfficeFiles_test.py @@ -0,0 +1,38 @@ +import pytest +from ExtractHyperlinksFromOfficeFiles import extract_hyperlink_by_file_type + + +@pytest.mark.parametrize('file_path, expected_output', [ + ('test_data/d1.docx', + {'https://xsoar.pan.dev/', 'https://www.paloaltonetworks.com/', 'https://jobs.paloaltonetworks.com/en/'}), + ('test_data/d2.docx', set()), + ('test_data/e1.xlsx', {'http://www.google.com', 'http://www.yahoo.de/'}), + ('test_data/e2.xlsx', set()), + ('test_data/e3.xlsx', {'https://www.paloaltonetworks.com/'}), + ('test_data/p1.pptx', {'https://xsoar.pan.dev/', 'https://www.paloaltonetworks.com/'}), + ('test_data/p2.pptx', set()), +]) +def test_basescript_dummy(file_path, expected_output): + """ + Given: + 1. docx file with hyperlinks on a picture and text. + 2. docx file without hyperlinks + 3. excel file with hyperlinks on a picture and inside text cell. + 4. excel file with no hyperlinks. + 5. excel file with hyperlinks inside text cell. + 6. power point file with hyperlinks on a picture and text. + 7. power point file without hyperlinks. + When: + Extracting hyperlinks from file using ExtractHyperlinksFromOfficeFiles script. + Then: + Validate that: + 1. hyperlinks extracted from docx file + 2. no hyperlinks extracted from docx file + 3. hyperlinks extracted from excel file + 4. no hyperlinks extracted from excel file + 5. hyperlinks extracted from excel file + 6. hyperlinks extracted from power point file + 7. no hyperlinks extracted from power point file + """ + response = extract_hyperlink_by_file_type(file_name=file_path, file_path=file_path) + assert set(response.raw_response) == expected_output diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/README.md b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/README.md new file mode 100644 index 000000000000..338d38078620 --- /dev/null +++ b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/README.md @@ -0,0 +1,50 @@ +Extract hyperlinks from office files. Supported file types are: xlsx, docx, pptx. + +## Script Data + +--- + +| **Name** | **Description** | +| --- | --- | +| Script Type | python3 | +| Cortex XSOAR Version | 5.5.0 | + +## Inputs + +--- + +| **Argument Name** | **Description** | +| --- | --- | +| entry_id | The entry id of the file to extract hyperlinks from. | + +## Outputs + +--- + +| **Path** | **Description** | **Type** | +| --- | --- | --- | +| ExtractedHyperLink.URL | The extracted hyperlinks URL. | String | +| ExtractedHyperLink.FileName | The office file that the hyperlinks extracted from. | String | + +## Script Examples + +### Example command + +```!ExtractHyperlinksFromOfficeFiles entry_id=1249@93725c86-540d-4ee4-8728-f0ab82b1cb46``` + +### Context Example + +```json +{ + "ExtractedHyperLink": { + "FileName": "Link.docx", + "URL": "https://www.paloaltonetworks.com/" + } +} +``` + +### Human Readable Output + +># Extracted hyperlinks are: +> +>https://www.paloaltonetworks.com/ diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/d1.docx b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/d1.docx new file mode 100644 index 0000000000000000000000000000000000000000..8eb83b6fb23008539fa7aafeb9be341216e04351 GIT binary patch literal 27905 zcma&NW2`7a*Cl*x+qQj=ZQHhO-ecRgZQHhO+y3tJOlI=_`6kmzcXj$lCzZ9=+Piku zl9vJoK>>h(fB?XdS5XJ}9~aWUcQ-pnV|rT`8$%OE3tKZfcN^>CL>bvZ283X_K3t;P zO%hZB6xQniD7LG=z-=*!>dibWYZ7PI4w=1*BuODEM^U@4BZsHYFH+-qC+47MNkfxi zAll4hL3D}_@AnPvME)+yX37C4lpKyyEt#DziD#1693MXZV&<6?DG3W4i9z`$q-sla z{r1<99C-yZ^z{&^!$Kx#FiH8cSHUPZ7&QfF@y;0H62YA32+*V$0l{0@B#=k#`dyz- zP+13?lCFJJ!_8b=A!Eh2fK9Z)^*l1u#qWmeLKnSo3e@YjR#PagFcycWRmN6J0H$F6 z4p!g0I$Ahk4lD+L$%pdN76#;Idyqwf@fb>-wf(_vi(hX-Tt%b7G0hB)lSDTbGS`TQ z4{zztqC9jjqSKNNr~}m6p+fm*1nLqBE&(0k1c12iuF@|u;0$IWBpiB(OajovmoXH* z7NfC2!> z|Nr8I_`h*-GI4hPhmzBOVM?C1-DH3n&DFm}ILmn}lwiYf@l>zBuFF~A0U#c4LGTes zI6S^4A5B><;@>wd757WvTY!<_2TDd4N+OWBAEL1+_>cIpsEio~Yst4S(Zz@|0K>9b zx4-IRcRD4JTcpKetPrk_9}ZK83W;v0aP$$+uZS?<{0V|!Cci~^sIsRnb54y4&)-_j zE3!#z@h7_}_Ao*wD2>HCAaTFDe9E#O;y=ZveTyqo3NbHaXkMwD4RjzfJ&yu=38OTW zgvJ*Ag11LjW{lm8* zSEz|Q>f-}{J&m1a!wWtJtbeLTkdNB5)jeQvo22VJ4EcrPH?5TPbYd_$yy&}@)=$4l z;Fm=3mFd)spofy*UCwIl>)!xSedc?%IWhwS`p8kgrZ;akrmb zp$=?=-MLpr>;6uc{Pg+8Bw?!_+8@PgyZ~1}mw?Pk^DU5Is3A$$Ay%75*&{X%{2&T_ z*o$L?MD_G{WO<<@r{r`&u>OXyvzM)Yu|jWkgVGjM0DDHTvQQyXSzVAW3tA69X4t` zHF@z{5Q1_~K4F{_LKoNr5C1eF#gUf6R^WO+!bw2}$|jo}m@;D3Ot4z&UB z_(y)t|10_7{}1_{J*-XsOa1NCYugP5l#p8e*S`(3MlH>B-NFZ^yru6%Gd!%{GUo3G6Q`P$p=cCDF#tUai>wl6EtY~R)=oKH0cjIAWQ`{U6X?Q^bl}~|_^mTE z_~COpe{kF?4l)8>6wAw?8e)Yp0_BSV&I|d~+l1$7=TMc0acDV{on$Bn>JZ|rBb9rs zOhRR=wR4R2%qv^iWv?^!DR)ykcg1YXz~RJhk?p1YrM`ip)ZIf*;*dyXl(@qSG@2Sl zc?u=rR+QohNBmuA8P4u5EhyZuAc{ItFkGeYS(BIDH^s;KHoAbi6|`HMwkA5F0d$hs zgrleF66!B0A3UiSj}Q)|1N0lqw`+|m&A%kW+4w8e2`8b~bqG8ANx8_If;Q~0X9Utd z4(b)AJA8%xpUp2AGu@KBE($4(qzMI%oy~bEVzb-Xj!~x|HWGaqQ)EBZ$NG&zDXtUW zV)}40W%k)`F<>4^GyH|;h%V!4E%1dM#=ph>J;;h>#~5oqk< zcJ5R-WfgdqB?q+$ePZBrMyJeDVBu(X9d>lzE5=%r&$*^2rfj%W*1#*g5Gp>)^E?l0 zY9R6?jmE@v%_h%&RJo z>Uh}n=R26;jm&0$ir z5INxKnT;@7^?36LKpH=`vVmibOeh(>$l!DraJejpg2ep2%`?Y_B7v54C`xoeb%1hU z!4!tJ4ofDFAxaJ+Klr>p*!-WUQj@eE_p`p48N zzy9wUl%oJQ{4pzEWduG!UJ`9S{g@Pixon>+zyT6S{uz(dFOi7IhoS5rv*btMqNGGv z1P+vP4^`8`JAroZ>2OovjS~}de1T+7ir0Hmb8vEo3~qRW8-SBFpjE2vP6e+`5H9nM zjCX_2`^{odMlz7E8a@Q35CX8rgnZMqWpUY)zqV)Z+bwT>R*iX(qt1uw+ zH$39(6MdymGSl#-G~NS=MqHXIwt12i;Hroq5e4HxihTCiCaq@=Wa^C&s?L-7yXqSU zOMfH`S@PE;Sr`WM41cyvM)f^iMG-M96r&VXL1kyy7M|U1PkJvlVxz8?FVy0G-jqN5 zs^zu$9!a*o{KyT;K3l#Il*zmJfzwkRjeeaG4y{U8;@w7%PK_Lw6Io$4HC~wtxwLac z?G7`;Z|8ZC4&6PO%O6kM8ln_Fd-ioYyF6W7dCGciGA)jVT6d7R(VNCzp@{DPI!dt7 zU|D#35x`5_P0VqWf-i#B4^jK~?ulma9!zadOc#}s^2*juM@85B#7Ts@!ujQ4(CB394fHT?JR z206I4?E8zNv)BBS@l1QL_K#j~K7Wity7VaP&x#0z?Fke+8V|1{sye|I+o-bL582E? zbAzhH>MXWx)KheW_SvS0PTj$pB z9eS+&ckr`cT>lY*HLjKTiGM;s_J0)uod2D0^&CyCo#_9k9MJveOLvlt?ZAK5M{``l zJFBwhQWhfmi>ik6G9vK$3FC72a>no=w!4%NK#E}zDD_$BpU01nQKO5|s{L45^wr@S zLqceOC9E|wxJ`E-V?Pn0xg`@NO<;$tp>t%&-45yHkt|~ACnms+4ZWwJhAvbfa#8Y% zPg{V5^q4N2gsF7ssM2Xn;0zH$g!W~5){dr_(~23L8d(hcy|w!Nx@=OCA-mR%i~IE_ z=|L8B353oa`_ir_x-lG>j0&<1=EwuVg`rmeV1O4x@8`<}O<`qC26KiVP`C(izd#zO zdIHAGZ1dw3(}hu7B^E3#MZ@}sG$naC^idmj0^Bc<3kk@|CY!F?f315yeAh$IQe*Ly z$Bn>SU8dxat3opz)O{_M2tV`)*o*2;U6-$tjZ_CLqU|i}tg>|}7-HKM7mmTm8Tgn8 z&;Bv2y6pH?tR2MNHbp2HBnWH##0XOE>Ed!)AOg0UbGs6%*vlGB<}#!--J(FC}& z3DbwU2%X6i3xo$E)_F-yD@zY{AD{FBHCVkGY@7k)TkQ4dyg0YJNAuZ3EV5oWQDhk- zbK7TGnP+q50MIe*w|o5ms{d%sXNl_n&4cRSZ2$lB66*gBM;jAk3j=x!8v`>FCOUgt zvujTkWn7shQd{)ZJ#;s>*S#D6J^T7SysSME?XB(Y04w|MHe~L$&c{cdsVa}G*L2-V zuk4HM(%GAu3Z2uc8*x@t4Hgt46bcFo77q>!SPBaBR(LKP$df~i^PxZp&|oTCV$xzV zdQwnjCx@nn`qrR;gh=THk)=hP{#mv#@JKD8LDV1h&_L6_bYG01#G`0m$S|S8%oH&i zY6#Ja-zpvCRh$t!LSH0AQYA0CV9+}c)Q^ft_(C@ht172PYM0NV07oW%UCEcexSC%m zYAK#ikK9iTE4oD@0rQHHno|?iS_9OKBUA-^-ZQ?)#LpuMME} zr*56+(^9Ld6nUJc)B0A&ao8}RG-I=+pD)hS_ zB-+&=JJd#>8hV_OlF46=BrvmuG1^wVy~L-u(9gX-Yl02aYIW^AxIsOQaf0k`my8Tz zvIWS?L|Bs{pxa|wa&ctYWr}ihM4_-Vt2NN7i<3E$snJ_vsL;TX^Wi%53SLPDAbH8N z(Z;2rRM5|%?bp1;3y|zBPHy!T*R7WKOt2TF?npydB7ko}e^PgHZsr~ESe0DYmHAij z5f))bz3rqUok4(2M|c4;k;;%eg!@N_Dvc+WhwuVM4Fr<6=vxQTXYfZtJX0O5f6N=R zKPi{wbdRkkT5SUmMh?MY-tW{w2yF4^Z6}8h8fur1mQn*I_2{_8#FthxRMzykS6`*! z2j7rAhL?!#pE%j*T>ldO2JtEn88{>HyjNf}`ncJJIoM;bZ%Pi2BLPT~? zS*7CcjSPGK3{>nN>$ti{ske61$+OQOz{qs1`G-}ga1N=EQq`;xx;wk4(P;~z z-lx9vJLmCVEQcxs&MxS=>Bxbb>}U z3h~}3rvZi@CV%N178X|j^O;b=(2QLKcdLvI3V4xfSEgh7^21mXfx)dgu5MPc1cEk@O$GG}yCI;78yoT6A3g_o_Fg={YD zpzaHjjIb&rYbD%+7mt?P!uOXl>N!uMNS}eMuxJUk#Dh;dTbT@Pz!d`LI0eV@D^_sN z0K^oh4iJWZR6bUbYzO2B^JQ1WkQ9@sO$6jc}ogBay{#R2+v1~Hu~m(s4Rj;yDIg2oBx zsZTJeFoqoay}1%c!A3Ov_WF;T^>dr0ko@kSC&4s#ZO-a{FS-Z6AUYAPj>yoL58 zGAS%6cgw0KprkXyWH@=nw_WyKFgU(NZ`~{#jP=pc1ec7KOeS9uKAmd0N-~rwY{d7x z$TK=cy{ESz*IoQxl~7efTOd2dV`CVd?8NMT}4nOaNn0em_sTV zN+m_-MKC2@KHKh-;-Dvb;(PhJKDy+(v-8mZSGu3^EB@GEIct0Ab!+W#nRwl3c{q9j zAlr6y0JJ@$t(hH*Dk=@GlfQtp;79IoOR7bw<%(RtB!v9jtlCeO z7#$cI9_J}#u z!%{&LH5B)j5g(tPL)^K_XulZCmt&1(rU|ZLoAFL3-a^__nhcXxL%39Cv`4VvKx+6g zASL_0etO_*;Gh*kcM0YMhGl25WT7I$&R{n}_CDx@0GWzx+OJ~TK?XVWtW`30DO0XV zZs7*+7VFkfVoTgpqEI|cJj(Yz!3^^Ai>r<949y(53CYp^dX1iYh-YCVd$U_ZLsy)O zjr-|Y$VDwf(uS2B>%zX=Y1^{Z&5B3Go^;y|+g7`$ddz%Qy&^!F_D2U9^9;vlI5lDf zYYy9HJ*lm&O^(MEZi5qX?#smoC>HBprJe66QnC2AyjF5{lPkWc-M4{2l4Ox6hnSBL>BMtRuprO0r4Gl`qF@Z8lC2xw4mvc?PiRFrMzoUuL-v4w zD&j^QIfKcmu5`7UVHuQKbBU31@KKgN-Ow_51>AB<%Joiu1WiBKXC~Ro)4TV3Hiv%aSyK=GQzH@KS zaa-{8WN%>UU|A$Rz^xA7wo~z!Tg&GA^p^p-0eU`ZKEAYL%@HUudUNH;j?=L{X}Ry1 zUzZ3$`46ct-Gp$(7WK(lfI2dVVc$Sux?rNv8|Naz* zKjdmS&&revB3rG?n9)Juj|)I1^dtH;HhlQ?-oYG0AMfNi^0d%I#Cliyqe*g<0t@{l z0U$tcdT?F;0qahD39)YdnOeL_yhDRj#Qfsd{y{RMp(J8tcE3jAE!+g#gsL)FV(v}4 zfr3tZ;>$t2)A0SllA&R-Tj%JRWD{wn$wXH5*1{{) z(t~mJOmvP4`D;LQKihE~3@C3e>Iv!YZ3OzbT#J#|v&y$hEEoq|gcP2gcVG;6W$QF0 z+^vlwEoe=igE-T?kLQP4(96;A*T`G)b1!?&^y!#XqbI?k=_Jdx&cCQV&OOdU!nF$3c z`5&d($*TcFD-v;Ly~SE%)#XI7<&w$83)1T}lZ<2RGI+xwxjk35o9@>%{<(h91>Zd% z4ryj}6tSIukE2Bg$0|8<$p(4 z-%;ypZcd9r-=`0WMl+w0YY!{Q?DDQpRJ}^fW<(=ymz=IymuF@QEsbSc^j@^iWag!Y zhYafr&qpvv@Tfddde>`_b;=O9O+?nFwVcZoJ<7_bM=@j}e_KJgE&M7;A|kUkQZYQq zz{}eCZePI*;B#vJ^7k%JOZ6!PGvP2miEtw;cvFPbX+jM(ZdKfq9t0Gr?oG_72H*S3 zjriRLAJB{flwHHou6)5cS=>}=jLwWbDk$D*U5sl{QVTKqu8GUf?X$_-#U%@Y)20 z-PHQnbu9M2PR;0|Hdod|s(&@yXVepzrza%^eT9J_<3K1khDPF-sd5eY2L`5`#UtUT ztV06<#TNwv_eU%>Ly6$00=QA?3^OwBQ;-gYTGTy9u#oU-(m4R}laQpf!J}ZeD;8c2 zf|t9bfgr=tiQfQ62Q5-Ae%!qqnEU@Aie-HOCx?{J8GhZx8y^dQL4XbY@KXjhVczo! zDj^j0`vwgN|L`ArVkFA*w)q#1=JN@Pc;`_%l1V__;a9_Z`v2N3I<*!D3}O!&7!HXZ zVz=w&@HkVyHZywJL|S)to9?WbXQ24-N&uUrS}fdKeQxEt*ajoQ_e_FwS}X8Jar6D2IPpE}7<_pjp|kd(tth#h?D5l}0dz@YS%V zSNF`lJX=!f^BEM%uGN1&*Hn>Yj#VnB-`?7F4qIYDuE74DE<(^$)QomV;Z@`)OQ@O` zmz|CTv-i1owKk9NwU~>R%o{2D5_Z_q{>r-6EY{6?83o6vkv8IPASTz&3(B+T!MK9? zQK4POs_Qd5#-dp8V77LvPF#U`neXU$bCFn=oN!JPP zKDd2~+2fI`z9M-knZ#6w)qbk(kEgLz5c3p@1K6-;A>X~Und9tvzkBuq9!P&))@vS% z!cBDCssm8NX)oUfR#Yd@-no~thL*z}Psb{7tzvZ2zI6OXGl(5}MZbnvX-9p>&^!uc zdbpC`t?s(n#1K4p{9aPNcrsgE{l3*!c<|_qJxZ^x+3lqmg&lb^g8=u^S%`>zqNEK_ zfT#m5vd(Fh-wt(Y>)@%OU~k}#tFoN%aH^7H>cw1hCPKDFp8S#73qIYtHDPznW~)wk zdu`Lx_ydOR$d;7!cg44AdEaWmjpUtt0+lzv2P=%Ho3a8)N>j&iI2sGSt~i-iSJ~pK zq|GUytZEyq;I8hZ$CyzT-l#;+`*Wqq`Z+PIR2#H5#z3qNb!~3Y+wKj1!=E_`V!tG> z*z=oTI_vdgr0s?5y#R z1xlh+BRaJ+uAA>e^(T(nbNnOLlt!J9cH!AJQ z-Hj8w($hRKOH+x>aXUiDSn4FbUQ3ixKKjGsKR*A zvwF|wuk^4KunxdXdu<;={^AzGQ(^QCfPyyVRx^fRP4{@#D=$nva4;zF=uB=GHR7?1 zl+86BcGYNF?BK+&XOyY_53ZYvamd%`IMfF?lQrugo`|AS022&I80*anKe0vhVsf zxF!RkH{IV*J>`MCsI<6d6@6-nq;geeM~w0b^FGvzN@fUKM|+^LuqoOpW3e_!T6oqg zER&|u3XgjB*wdARGDxs*=7!~E_tmnoq|Zu7Ir2)wtK6~ds@;9z_WP<*@^k4Iu-|@y zv!fm(ezH8c^~MO^%5sqrgtHo4OFSBW1oFbH0}u5ak7+xG*$PJtg_Y=GzqSEKQK*Pr zIv%PvqQclnK+=o#bf3KSwEcTG3NKbv($AFF07a218Pp|H;*gBt_PLvfd1wPB80_6p zGk0NWWg%M8?u!oix!HMC`9-P$h`deNyv|n`do{)s%-)t1=8U7I5>7L+EBW44VBsow z#4QY#D}QmXaO5^Gt~oN|Cd@5ru9(yi49c5x)k2`U6lFi?#U~};QGqFK9MGT(JMmJ| zZHQ?%bKZTATsX3gA3>=Tl~>o1^@;lkbMrNhzIjyUk>-`4n6_06x$gs41=u z@vIBlg8kEa!b!;tiqW5LN@)#H=kiyN(ddYvN%SW+g^q#Sr!$f9Ah`2-1h7^@tFi@E zB`u1Wj0ywL|>STst(aw9H!SOe#tKF+EKAZj&LY337fwEp)( z{&}MG-4{adG+k8b$zzq7Q!pdXs~yAII3j*FpGfPp=Hkuwqxv;8iID6wY``k9nWJ_s zX~{#UUSdH+R==q+EfDD*r7;OY z+-h{6AVkbl@4*_jYNqu8{@|rgG6Wl~5?||krtUiRAeMh-b*$1$2Tt_U?89`Qm>|sn zk7QgT@aFc_oic3cfEp6LR6as`BW^MN)^dj?CFX5sJSVx43<8TH&U>ei^> z+34D#wOOQ(5*gj`Kl}P%MY^DGbP^&*YsiWyVhf5fduN*0 zr2)f+{K~*@g){ixQ2jV@Xb~0HZVvS&xpS7c*MQ5aY+krDib+TDBJUR%@nXX31BFdH zk3Gdm!Sf+OeqOF=8PZlQ%YMJ0e+GB0FOVyKOsYE_z^}YQSbv=$W`t%B2X||d9G1Lk zCat}GC-eARkSn;5uftsXAU*=5pFt+Rn~o#VDQqasb^|ySO7PZA_-3Y=Ye(2D1=_z7 zB4=*1IY@-T*@Ux@dv~kI@{B*v6P{iBjb;=nm$T&t)2{C8{CckniN!Tsjoj+95!;x| zN&ylSFO*PfBc9i&fs$`bC>70sO#hV8=<>1Nu5(+T;g-Id1Ip$d4vvs^$GcpFl|zH& zOEahvADDWW4QARidid+Nnon#jD-6Ld!=3Avn8`rPA5YqgFh_YiMYuio;ewZ}R!5BQ zY0n_ThzM()c?GM{_c3o5?0Wmdz|GIjj38ndauYxrN{lo6I~HAojwpCJB>75ka}H}` zVGCC7m>jMES_D#$4S2}oXZtxY*G8jK%4;;GR&d5IzPD8C4r%z@s1ysv){DZuD=CMl zE(Oah1$&`&u#2c^da5oH$}>#06^Dl0loIO{AMSz8ry};q;*JYPoy%?tRXA!{nB7o} z@d=&P8-~vCxIs=o*86%`b^?V*6oI40#tsQIFLNN>8FQzM;O*NC!YTtb1L@ibH#o}C zvusVPTA-rstGLsfuF`F%ic*e?6H{0r*lH;H>)MD;@rGy zZ3@-Y%4*_I$cD7>98PO-A60g?vFT787NmqvQYyQkNQ6#Zsl@zd3_jOIko&7$%IJA! zpeR^+q9vKUX!;dU{BD4?J(H%~(BF9Eis@5}3-~#f9%9_&Y#vKzW%JSy2$srg z@2dC)ZH>0oyFp=pBz+_Daz&4&^CgqC5vEHuhsF}D>|=sA0YZa7_V~`?I8kW$H3iBM zslVB^(mg?Z!B{&AcnSFE0RCmG^6#;2=}xU04u!Hq?mutyJF9}aOG+CnIqun`=M!DK zSWprnxF$8X<`y405EU1L5QbS1Ms7E`(N`cFKRk`$)_-k&wlqmPsh|OqdJA*SI2lml zx!k60a@BT7RFfG@?_In$)tX_eo;;*NK@~}wdhf#-4P508&aqBpnr!ONvKlR6l?PcE z?8H{gO4%mUD-37W+xiTMYmToIHbTl}R8&0k)>(VBj_AE+p+^p8^R|7Yo}&f<)7sgB zJW$C~a;&%BcHWP~Dt z(*II5jYn0Z$-ptm|GaCdj`t0g9H=Cp@tf=JHXgh~+kM<-cIG>vS?PFKcu!q94I=t9< zkw1I`8nIQF`$^u)m$AxO7`vU@S4m7Wv#V}nOa%Whxrvxs)dQEe0Zt&e37)#*4x|2* zjcTo~Ss{1DUYoh`U?IQwGXjbaGCs@xq4QVz^!X2ySn`MJ?u{z$?JGJuHJ=olz91fI zD!@o8kq1#|S-xodwYszFc=rgQ=*ci@8+0xjO|3>a@x>YD499JcW54A%VgA4Pk9*x` zL43VX`TkhZzpXk~w(MK#wW_Vcey6nP!X3xtBS~$CrI)VZC^f+( zr-PzE!}5d>NzLnrw}7#}`L<2tELxHpB9qb4& zS+Yje07v)1aHb1$7S_Sbwl%?y`nyD;^KU=CAc%?pC&M9x9L+%`wKY;h7Fn{WIdmc- zT`**y{6*d9r@lnOr&DTpp-P^^|7CbZ1UvggPc5J_U%7^Eaf>=FE5f{-=@E(?sPLlw zZk#=^tx@BltNTgGQt3-l=OB^{0`u8htNKM)eCq~!u(BPeU`x5Fdmx0DvP&TYqaUXDbL>>hYw8?~B=zO|~n z4P1DB4}xBcm0$c1vnw(H^JcsPZJBN!wpWQ;Tu9_wXYHa-wHe8t1=2iImhNXNDVJJ6 z5oo#Sk%F!!g1D>i$fNvJTJ?9(A{?`to;v%JNEn@| zxJeixh96N|ih`@fhOz*U$0W{UA>Y8U=g3}%QsP@bR(BVOp&Vnc03b@U2JNhh%n7#s zWCmE}k*M5-?g=6lh~3Othsdp#%EI|uRvLQKX$HvzXq@gL<>TfV&MfOawKPr^ev_M@ zR@D!mWfa$zWz`0iH*RrE48`-AA_~Gx*V&|qUcJn2I10$0`1hOXqdZ$eX^KYGN(5|E zmvXLS@;tO&IL?am#DV&ds){?0(Pt#MrP;UKL88IM&as@5%Ck%9) z;o`6b`6c-B1vknXa>&Q@vigHuqd2zw9365IgwkiGH+(l_l+hNNZ~3c-a#t^GjIU#Q zSi1SQj5J(qbWpbK$kd6#3l#)rRR-K+_hN5VYCyFBpDAu=0|u_|;6noAQ|p!Wst@2N z2y1E@OKl4#T+L1dpwSXlCad^yEK^j73<+!ASd5#oxLBg?mQ_KIIZvY-4-SHOfu}^R zCr|$2YL?h);7s=(XSA(Wh{qiMGvLW!B+5cuoLYRI4##69_O3ea?^slT%{Bp`-|7=- zlS*13ac~P`dGaD{`bye!PopeM%FomOzLJSb%T(|lP+odpT7&NecV3Q3sX7jKl&UIhf7BCHqiRbX zbd@{ssUF@R*b>D8N&5KSJ>73po?ULGQjbxz2=rK!pnf(^?{8~3NwscNS+zw!2U6Zd%*~Bm@6X|ag+Y>+_20U&>Rxj1{8ZQ{FT3&3YPmZZ zFwgA#`paUm`<=ica+w2N!WJ$({aY=clriTXOq3tYgNi1$)9 zg|!ROV~hkjf{kz#APHS^Zmts>w#m03qylhMI!(K*hVg3~e*oW|J5j3GSDazI2$|aD}O*=ToQSxbB3^ z=@&ngOENhFsN6NZ-NAaw%fhjMYjPhgA)|ZT%Q`3TqOu_)L6p4y*P9P zuEj;CZIlJY#$(h*y*4?CR}na%@m;@Xo3zA+pwn z!p&gGVCwP$6p(8Za!WN3N*j0&hg9ULC3(WOeGWl#U8PzV zyC={n)G2PbD$?%>s(0@^OUe(KPz}EZ*tM@-& zae@oydKF7q%Lb+?DnMjG!>|FW-t0)_+PDmT-nUElL!al9PS!-Vn+f4mjK{E-B5{ms z>T`!yO%6o0s^a7%XOFg^_KCQnCd+efW_Itgcb^w;Nbe^N4((;Xt@|jmkWyVYlA?z# zrPBSoC}?ks2GBh0khc=mlyTFCv}}HG$t`^G23myjJ(9;Z9J(g5jbtXkufgm%(5A*- z;3O2LH6nff$M<7I##8}@KCj_C#fH+#@&6nvm^G!emJU;Z_8w$vuy!LTT`**Si)<8ZycEh$i{dyzwX@Jf6W98( zd3>UU4@>(?tT?kXg1Z?5zGi##WXE?|q_m-Asj>a+ma`f7uDX`-mSXAW&hcEzT_PBg7q< zQ`b1x?7GpsFwYr-EGKG7r6Dl(-G2WJON7lYC9ih6tvB%jRr-ky5HTwPU4y1_P@B8k zK6o`wTc`bX-+axYZ>TCmp}%(wdb2`z;il2iie1%-$XkNlEc>o?%v#QucRKj8K3W)q zv*+P+myWrj1e>6|rVRD4cVQkN($#ZAR(?N~|3TT{gbbJ;XjwPjCDq`=jE#vNt`{wk ztW-!?c@63(khGVI)Im-QoP^!qeaL0(M17_`a|^#YnEJI@j+hD5$M``js7dd z=Uvi`qxq?Uy-0B#5K~9dI1R7ZtNEp%9f==Tnc)bdT`uYsdY$-8GwUK~{MK0=*Wydu z1`Gn%24wt4T}g=-^7*{6LBoLrZzmPUJj~@ zq6^MSs?i~`NArD|0&4SY!{Pn8co(G$DciW{Zk3|Wu$KIF`tFeSj@JE?F|M;$)Q z&a29bc|u^q+A4Nr5Lm+{+*#e;G~Zt;#FU$aIS7fT$es^o6#})pp7bxLxOnw<%U7^= zzrP^9DYV)Hs!N^wu^&F-Y4#Dn{ag-y33J$cF1L0Z9;iKfry(?qKmZ3YkXtLEXCb6G zgG<7}APc7tiiWzq71F`47<-+eNm>#Cs-l!Q0lVf{mOwI6IX-9xkqA8P)-`hpG7$@? z|7o6R3yUcTUKEKHF5-s)j6L%AAa^7sQVfV8lTY2(Z_w{8#B0~!PxF~esr%j5?`9i)|NCV8uM_ezRHzo5VI0&muf!O}>DCLBbn*Y7ccftEkoTJa~#I;S=6 zTy0(NKPAbWDU@l2tA=Nj`2M*Cmw10j9t_L(AtE_;*mR^@p%FHW{bYgLSh*JX6`T}Q z++Q1w8ZEMs32UmU@_Xwy=_(OKLIioL*B-Q?R;JQuv^no*NAR2%wA*%E7 z|ED-ZSDw`^hGJVC5len-Nt z>HME*&9rfckAZ+3%4mk_RPJ*vmg}PptMr?sh)PoCtR22DlxI*teziIC;ri-GoZlxG z#nTCXJg2>3m(QNtIZ6+c0BetZie`YDSFKqyNu^*Dp^;sktgS0m2dqEQpkJ1yiw#W3Gpm!@QfTk2$lQmhqs*{ei1Fvmozy#2Asw|?G32}%o0IS1MaG)}vd#nM?JBV{Y(tVYOUZ}xtLX4_Q z09|;ZsC#IqRfECvC70zi+t7#X4AAICxUGTrJrb^NbUob;K<&~pG@XRyW$n`hN9+WQ z3KTvguMmuJ+r>=>tF#x8bnoK%ohU90tR2Sup%c>1(V_^c;SvI2Zo_}H+~h-`NGgbe3%tmVV5iz+wvN2E5yZk3%&?$n*|p*h5$#U27N-2 zTv|4IWCG{12+kAh8InQvmp!xU5Xl_o_o=%%3+^4FxdM8kXFDB)D!qTM3x5?RcL2!K zEKPe9=m)1;PwCKkeLg!M$?!%uL7)zNoP2k)c85>8s&Zy~NoPCis_~nc+2$9NUc;DL zD#@a@;xv9!^mBGY|DC->Ob-1b2{It834jKf84$xu3hC!<$9#Qc3}%ltg}j-hW(R=QX)@AxA`d-Xn-Fdyb_IX+>n$$e-fGGu#( zpGSxti3{WT=ked7J4jY9R~F>RwNbpwav!ak@pq!6>|fUl0eyXE!7z8Q(V<+3ZE>kF z_3S62gk@$P<#n5tbXuD|m+k9n0i?67k79bhWjGj$!#SU%NLR0~CwCmE8zD)g0?F_k z`b=4^f$vg_BerWCG=C!>5DA4d8w!+gv!d=1#8g&i7q2ubf>)`6I`PX*`~?!bXt^_C z!!F-`Lk3FBxa~b}z2pK5?7Q`CZ^64b+KjBsBW1d_oYlvMTHS{SRkjh(>fpjO^73XO z+swC8W-rBmf!=&e+1=We8}|-3jF;-w10>u%UnNPeogE}wE5m`Z((e*wNfYVzk(3f8{1cG#gAECZ55~@Z=xG$t8g2I*mDlA*1?o|X4)I^77E%^^+ z-eu22_j^zKE|22vj$%N=K;27dbxKY6O|5w*n0L9U5TMw>5f)iYV z2X}V}?hxEPxVyW%4ibWEaCdhI9vCFJ4DRsA{a?MC`@R3|uCD6op0&^EuI`>W`|Q2e z!FE#O!8am*NI4-0u9_WtC-L!;5_`ay;^Xbb=|`b&C+uFO3xbcY)-#}UrxpN-5?b+v zV+%JLF(jaRE3)4MfL7GLe8rc5`8HhdXA%m>k#T4x(2#a0BRET1?jNWj`3fN<9nyzh z43)Qn;^8U4NoZAaBYI4|gAfcTnIXLy8Oaz8;({@Ab^;I5 zH5ih3cq|+#VGquF)6wL-uf^cRo0Qd8Dh$Xg;BE1V&sQkV`&1KEAD6g%`krL;GAI)wl0=oCuo#dox}o!ueY!7T(2d*RXRb2cSC)oecbcBUi@e9AaDeTZHNBxnFn ze0L_|_dr<^izDm(Ah(NLl5Pm2c$B+ty&mKkspM<;O?GU|Kta;2ptVhhmpVOx;jpJg zLv`ND@j7>nqhb4U&F9Bge!+fU^YnNG z4W>lWIOhgZ86y&Ae_Rn{vK7!nGwNwbSYJ7D#UvNhEpFzJn^&)j2;3&~CTxC^y?JDw z)RRi`wh+}ks`3um^^guIRdEjMcBmttM|IG}-p3%WO-N974ad_pgkA={iH+_GSpUiq zM4TJi8+$AzF+x7dbEfVLwqWidM;i`SNpIC0*AJByzvF#^dmJuyyu?nFkPX7y^rU1(6l}N29jWk8iZ|xgW!W; zBN049-c6=W`Zbwf!ERz?N?{h_&S7565$V#|(mJ2lgw|yE#E(f_(cz>h5{X7)cjO`| z9HczH8O?gmew~$`Ra53X2uiF=tWEr(9IsrLs8}jhDr=cGi%?Ylc`8{T>E{TxiGm|V zhGed=p8UGRS2BH4wl}{S$ z#oogA2^W%Ba#-3}siR_85u+?AgtWz~rzP$A%B88Qf>tc-ajnr`MEOO1q@MFWtGFnd zmS3pum8q94lRmizcLi0reJH+ zsg$c)$EjzjcQt-*jB*Wh4R9^GaX67DlpRtIt4yl=p|j^dDVL)_jx5O}36`YCQ{vn@ z48Lt9cX@WcZ>4PYa|qIW#?}oVT9#%8NT%J(N6BSllS_Q}43-wjfoVu$Dkc zjvC!=?T^2N-;X=awq!MJ#bjV%f@?#~qGRViSTiLxG(1H;XAv`lP^f2|SsPc|?H+S3 zy}jpb%afEV$5`An{V0blDZx=>Tw<2fImjuW^0qyRLVKz73Efp`ipA7{D(qubp+#3)5>iv zFoSr?u5E+$`#aX8maO~PjT!x8zol3Hu_X2^7g_)kJPI{}1=2inG-?IBH?9eOGLh_6VqXaM$)XYD#P2b*04zwTLcw^sCVV?UIbr1d_u9q4~s=2Z1P-t zhL3_b6ceQgH<7H0^+q$rVrMwCU}NT?ZDo0|j8+-1NWZMDU!tjPGujxqA7Y4W!?7b| zjIfhelu1ulOacoqlQ^gu?cL36o5yu!e*;oTS;>B+q@u7>AWBE$GCT=Bji|ziqFT>3 zVJ|h99T<5?`awkuEZ_)X{cV6qO37@hF^VHkQJl#dKPq4O`DCxI`KX!E-M5{+U9XeV z59?Jc(`}`!KG*r|>gPcRUMHR@o)2Vdo(PzhmBLA7_pxHQf>0}HIbzw%DcMokF&3UZ zM5{NoR6+&myKDHd*g(OgW$xU9{1HxAMAIHwOOoS<%X(0pcX|Jpi>Mu?P6c1nm#_nb zIaF*5On9U(=1Y^BEZbU!iko(<=NW4m6F+3lCV+{4-P+!Ia{yPvXG`5E2U zC-0N*wJ!Y_9qGTQUAYQx1%3|+McQLHexSTdTQT}+o=KJPp;4U7ywN+E}v;0?TFxcr@iAHYEI(^ z^2_?_`zWuao}(XLLZd?`2fq!*lIKfiX0>Oc5W8@-Zl{mbj&83Er2+G@HQkNCCYvJx zDg`P&#d8X7>vy6%6mFY6O{_M3Tt94| zX#3?v^*CAHcJC&*k>v)o@7f7?2&xN%MJ<1=xi_{e*4{gpgoyh>JS5P$IB?>5PH{Vu zb{e8ksxX#|Cs=;qaLT>#VSe?+yZ7=GrvL}|82LJX_v5hWdQ8;s{`u#MU}x83%H2=U zQIXx%`my`bMWY9a6=<_9+YPvp<~{vbb4k9veXkG!%=O8A3ArkIDxX;V{#Lhjin@!8 z63Jy0d#nKn!jhAL0$rm3N~8hPp!;YRVc(Y|EHPiR6w)Td}_y0?m{p4Z!bfjc)R zB!8b(&^gj!xg0b}B%)9@oX}7-UX`dh`*Mr&mvAsa4fln$l|1bor?~I#6X_{Xn?%h8 zLa^x-^4!>4rIv}7{cT9WWvVG{CMO4Yi;@B00T5x90O+@^x9V^J{@V%wK;}XI&z`P4 zsQ=kc{d3SOb&db+iz(7#!m92NC%OpkIs-mHkG4ehL|dDh_=KWgDJIAL96g_z6uaS( z(;Zn$!036G=*E&W3WGL1}8zm|13+KlHKIC zjEH#DRsx~I2C=e9O!jR*@%nq^yH{`@UPL_hr|cGD+w6@Z*`e;|@M2r!HD4 zaXl2$B8h|1L3(Kv0=bVK+?T8<5HFy*JaL)x$L$`@1~>VycAwea!c9p4$JB%#bYN}} z;x_7#L5N^ZPR_*zixu%~tBrt0U$ud>>+zoxuul=6 z##SEuM2&A)nz@KrlhxQ#V3Zj^@L)LYK>Y>kEJ@voGE1;6mY}OQsi~ zy~8KvJkCpIx|L;mgAaGBW|P@5uqTeqTuyZe-!GD3#vA<^@&T0r-68$kx-nHUFy23a zH3h&q$kc_Wz96;rN0JE*wOi9k^MX&BCJy`HN{#oAS{=BfYn#x)-%!PJ0Ca{Yi?amze%d@7q;Vx%qt5r43 zx1g>LN_SY*))Bo1OgGbjUhMe8o9-dOP?gRKChb4|e37Ke?^nNk>7OMT+dM1@mwg15 zC+5K;NtNEC2X!&Nbspl*D1|j88Aiu2psq*IdWyf8M1Ic$;8#Y+rY=H@6s?(O1O6eM zL<|9DF4dtlg>cgXG&Arw+y}h|B2cHBYkMF>{d|ETT_nY|K&pR4W*u*I_}r)@0n3%2 z)iT&*2(fD0+?jEdD<|qqy|TF2)N(_PBz4ZmEs zU|Y$NVXXK-v5ON$i9SR*c@Nm75<8!*7tn7G{0g0S-wjklZr8k1=F3-kQRE`f%V~%ntsj6aa(1!$nYo89 zbtD41{23h&$5n(HEV6k``DINrMEHPjjcH0|f7aCx1l0~dc8BIub33!k+++VDT3$XxKy~&uT!sa-+R=-xwIX;&Kf;7*?0~onZ|j z3cB^^a1+kPcM_)s@_1UU3!jbW^KXI?_-FRBeygx0KvGimQFLrq;{ibWo8~;;HYbu zYUXKzHLS(jly>8Cwp!esSk0y`RLYnxf$zogd>0fh<4~Q<5vqjuQRF@lB>8SW zas@t1n2RZ*hlYQBh7jS`fzZJyRw-iP9%q5uNyyFMV8o>8SP-ah{m&1nzcyClCU^kNSTa_nOY*&yR9G zk)LSVUwXKKE@I^m?#$HOnjxd4g3M}vbJ~hoOIs8TnPtXnL-Y*gY^VnhyAU+ZR*8rq zK{+qgp~l$IR6owB^Cg9P5R$tm4l5ZQIK}uWG+fOT@Ra3AmVc%_Fcsj9&!qho3md}P zDbJ<~gNEvkW^V&i*G_&0zG~7A;63xmT#HfUWq93|(o31M6iTiCr~|5=g@1Ov-}$X5 z6!S{2ljF3b=p=~MEaY1cq24HGz1sJ@vQ#Xr4mM`Hl?|Ua0BRa%Z!Y=q;l|}e57`%yayd`gF&qx6d&-bYol?Y%38H7LR2MW$MiTOMLOx=HOm7wF;D$Yc`QS z(_LoG(Y-C}x!&x@HSbe;%1)r5$~kOT z>O0VY4qs7qh*m$ODjFT#=<PF&WeWUk%`L#*uE)|cu zRtY1*rCDk5>H$PIgw2#E8Tb@RuIF#RlsNsO8hNm;qg-NCgW~JGV)-2`DKe~>lutY3 zkm^9z9QuaLVsu}3?(@BAu>+l8Vg0XR&X79kd9NSWc4baLz&NT-fhF*=m#$fc5;#ha zh)rVG47=tk`?5*IC%>5Cx0b{B-L2Sdeu|YGP{4&JkghK%B*GNrN#CM2Am^!X%p$INsBGfqd+6bavk`4C_R1l z7mn|^V<*-K6Z1X1zSkwjg8h4K1wtDEDg=V}#z@A_5#LT_FYO|193o4po zg=52C?LMrN4uN6@BMTk8ushkP@Y}`~W-S9U5x{YGk0-7XA=o>4RLalsx=-)Uf3r38 zGC7y0gp>|4vSbi<(qF+Qc}P*Bp1~?%8q=JUcr={d)zb6E-W768jMj;2$+(lfzkz4n zdnsUi#hi&UieRZrXL``1Ej0wM9{*sL@XMi1E{yvHy6N_}m!!VDmqk+C$-Hc3yW9%B zB=inTUHC5RPfYFr9P=t{!Ql)o$Ty!bB~56RStH7?)yk(ObB5?6l$5S7JNQ;31a8Pc z&+n_{&z_P{Gi(JckN&miuq0_kYWYX6zGYLr<2@+LUS!e%Z&eNPBXl#>5{V=sPlXZq&_J1iLI4 zHzls?^m4Nhvp)W62sD6vnq;LcK4A&Q@0qGBn(ht8ABSn6>G^&CL#~1fS$jTI7~P9p z#jyR=G%Twy!h;KT#B=2f z*xZY{?s8fPD@Mc;H1xC_e!MOWQl#&jjfiZ{cR0ze5S1X zT4MgI75-ClPW%3A#gEc;DxNu7?}X(#U>pHt@~Dd~o>!Q=$^7#`i6k#5-Pu5o`}=|W z``2{N8U)6XLJJ?m^{N+$n^>P(+|L=N?fZt+KgNz`?xtI11Lj-2kpLVmZBQ}>i>r%a z9sK~IxsQc7XjbWG14b5+Mq+sr#7hypFG5^x1H&Au_-1y7^^>{%Wo5KRtO#Be8hjeg z3es-2o6I}exO(j-j-Pww%7$K-RWI8E8vBOQCtQuIJlaYLW>!UylvykIVh4;6pRjQW zu(GerWwoBnkiQ7V`Ktbs-hB;mz<&<(w99x%1{ zWP1MhFOq#1zgWkW0A~%K-pL$L@?e$Xn|%FRtVT?)VcBK z(10IoynhPh{?e}8`vry}>@qAbTw{mtLT2|A`;WNkG`fA7NoZNW7G{V zgbS1aq_22Hpo{TaqpYS+ZDx*2Uu|SEZD7?rLKr}X%&S%}IA*HL^sL8i(>qA3gXOKvjkB~q(O)@Or+WIFuOgeE{@ z2RB5F5oIHa7wfAK|LRWE8xmh+#%^J)NSvIIGz&(?j{rYDKI8BEk2}}|db&aZ`c-Nw zCAF_|+zGy1V`spja976cun>R=Sp?T(?Kj;prtL~xg$Lqj2>Oj$>&3a>Hrz1nzW6o> zdSNYW3UTL5zR+pBA8CC;6^#4uP7+V^R*a;RF*9ti4R!A*JAr zDJ(A&xzh5D*oY%WlC`_f{cBC87~J|qYk3Em6295hvdoL1)7z+ZB8pgF1FJD)Pvl?% zhF$`ldPRmq#54+I7D|ygIW!IE2&EW)1jP?TMPb(UxH5Cf%;d<7(_xxYh76r3 z)(C~xOzgGRt02$=jf+c8v}ME+E5H}R-jiCD8-h{AwuN?+)Rzg;_kuZmSp`akNBVY1 zeyE9RW{XjS#>FoZhPs9Gx9lNl<(6CFgcqnTWl7{h&1=+nW0YOHhtSi4MUrwFL7$2#3LfHz*!_|Ltey zEg9W)wX+_$aKee4on@@yW}8o-|9&du2>~1hg?l7^ZmqwS2FI{2GAE!bw;PSNo73j@ z%N8F8=R_&q66)$~11m;i0Jk6aZYEhXMQeK0N%dupEl0jV2jqeV;;Opb`>u8W1{8Wr!9uY?Jf zZQ-lskDl>ix=6y)qlaWj=`V>Y8ZMxiBdL;h#qvW&t*xU6{45$fHTmzWv(L}6CM1b` zd>Q;-D`h<`LB%>qQ&R3VaBvc*%NeAkjX^&BT$k!^C(1py;r>pWJH^F| zO7d1;ZtCSkGM6P=43{_P$CO6#_D?$m?f1=?PDtf=ai&{F`iU{+l#x5B818z=kM~4Z zfGA7z6;docu48B1byR)AU}`XNkBe^~3U?wOM&91B&Tu``Jh3Nl2Jpm9rzRNJvT}h> zi5Z-H0!w#kF#K2(vIC=jLEn!Qpy^hqefS|{RLe6bfwiW5Q#AEryiay~xZwK1sQ;EY zX4DAb*z_t$J$=6{VlQy<5pwP^3GGXy1QZEmAsJpXi#yb=<>)@|3+1r}n<{ z>*6*|XmvQ?XW5l8b45L_epn%xCHYrAM0XeR7sf5t_V@b0y~qUeAF{6CCg`al@M1?s z$O%_iA}_)mujj*qKy8rU$0=7ou)OSAGZ*Vds?%hf>oJjz!LENQo~I#&A8pKx#Np2m zU@|tcXuK?0RtG*P`QPjIJU5UV!T>M2$r;9}MuVR%zBV#f2p@B0kme>4eVM96PB!8; zU|EwnWs@#Xf5{3?m*qx#UvL-gDgZ>|i1(8}lL9BQJ#BS@+{C6yy_H}3m_>}GqwwSQ z?n6UEH%aV<;LYMl?(k7S*6z`ez8*JIFurxR1|Zj&cD6q>>E?i6}IOBR8R=)KO_%5=luGvW}5d;CHm5 z{(jtzv?6!5Q=opyF#lC?$@9RL2+HTHVH%etyH zxV~Kq3~$17d8W;c2cU;PYsQ>ikLPe?e=HXB;6QP3wJ&{~_?%o=AoUxjYucHK2*UwA zHVP!lsfNaDTQSIjJESp>F`^oJsbM6mj}{>&Fx>uaa_onYFxYsYLT;(^rS)Pd-HCGr zFvoQNEPdSez-nJpMjEXrafz`eN8yM8TZ5u7$;Sdb>fcgCd+H_NpP8-KHFl2I1nO@q)C6O&HNFIgB`ukBmzo8BP_4GSg2fK^3vTo;PhIq9 zypEM0fgqFBY|fN#aG)GfW4jBPWfO3w^zBD%kCl%YWXg{t5!+TfhIOn@3K0*vU}a(V}V^HiLiq72&epvj6NL!;`Lj(!${fQZQ0d;}#*8(va9PX(6KW3u?aX z1FPwxyoEDH<81?{g(xk#Jf_<&5b-mrvMfW^lh~7MOqnOsQdWWjyBpikeB2WZ%QsnJS^(NKeuGC|b})Rco0@=bUy?YW|yjU9_SC;(Y{2$;iH>C~H7%(2Msf!OU?nZ8tJh z(Ft)BP-}QvpVj=(Yv-L@urnEsnq-g+gbQx3g6;HUqwtqwd*rgdW z$k$C4*_KXQMzn)pOP0Cc_zH7}_tOnkR0XY!7RdzU??B*{@5+Y-7svM{gR|7-7^V1=xOf#OXKPxj@Fd?&=GPZp#j4V`_q8fc}BxCpa9VC|x4E!EHJY~Z5 zpE#~aPCr>ew#yb0SmWrY3PB2tqjtA57-=Cq)0=#7SvWi*Vi#LnR|&gj0W#HJza;qX z{#4kf1ga1)^`*RE>pOk?FUZsY{TiGP8HPV1jL#u;0#t?+!p6U{q-fJ%*I+(L7jD8d zrx<$J)dHjijTOln$`sRO2|5;Bba0Sy3{XA<`ge7PS@fL9HW=uDZh=u5f_7Sbn z^RE^H4y#COb<-j(A-;S|G`fb=EqpYJynQ#Ul0PHeSE8@-CvJ}Pu9obIgafG)wjAA$ zNVi}ry{v((iXQMM);>}k5V6erV-^5~pGcYF>Cecdqk5w-_Gs`cD8B7d&YvE_3w@IU6&|sw9 zg6%x{TvdJVlu>8>{1DT810EK%w6I85Ju4SfElk%CIv}uVn33nU8#=$zVN>-r)y^~O z0p2h5$6kCGkzjVr=J2G~i)?LeUB=gg{#?%?;z7P?lqOk6)rqZw?pV7we9q?0ZN+*} z=5+hzEdiV_8ft8_S!VgqM3uC-yjYcpLExV(y;v-DHe)IPK<{n+zbTM0-cZ`2Z@MLK zto-__9`>eAx_?r_8~ze6u~XVkg%K&S#Cf6*5a;fm&-jM@lElw&a)MWE3tgf`k|4Kp zp5<{iCpO~U()4}FPiEPAXlb=65c6>L)OO$Jv`gE`o!Rn_NwF^_Z49hS+_~1x zk3I{*OVE+*Cfa5O;I?&=w?B!C&_R{+R#<6yzTSouOkBj{5hdWER6wP+xh5g)ElJkJ?^1(|AVdYWwBz*lKX z0L_C-0J&eUwEf}cOV0|(G*FKStJn4fpB%_2dUa8P)?p;vHb&wzCg_Ofw*obG_HEnA zH8%OztKm7!pG!Y=WIxaIHn*t%Hpi$a0|AK%__s*Z-?Bu1gk%2G{{Zg#Rs!@}JEgzp=Of3;rJ}Hvh!`E%@+9KIPw5^d`0P|C;|FF_nLU z|0aq5&%VDy_;2vvl<@zA|4m>1he`h5hW+lp;r|D({69VYO%MKu?)=}@hVmce=l=x$ zU1{-$J^bHR^maA=b^3p$yZ(zy{GTrV&Yt~G7fC$-?c$#W8vk_h_oMxvE+B>fcQ5{x pbo);if8U~i-U0u%5{v)u8$nS9=1*!a0O@TRev?EZxBBzxzW|G)$b0|* literal 0 HcmV?d00001 diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/d2.docx b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/d2.docx new file mode 100644 index 0000000000000000000000000000000000000000..9cf4d1b6f6fcbc805ed63429ffe8bfcc2de9b831 GIT binary patch literal 27729 zcma%ib8sf#w)PuyVojV(>`ZKHV%xTD+qP}nwyigq*v>@X{LZa=zVpw$b-QYJ@9N&Q ztM^{(S$KN2oFo`H8UPv^8bBhatOodx1Lbeu)z-m?-p1M5z}Ugu#+1&@+NwBFT4s;| zDOk1-kNA3%1f39#^Mp}e$(0omCeRFPnOhEgXjf5_|N=c^DG(P*gerux5= zL^l>P*M1BiT+^LIx$B%orzP!E2dK8ghVst{)Fl+0gE$}vfO6ejq@QIV=+8t**!K_{ z2VjUVV<~tpPLIqhYwbu{yoghOig}8ZO<_I1aWq9@V)1Q3sy+JI-G7slgo2hp74kI$ z0RVU)006oFQBKJJEhk4~C#Szsa{QN=lBaDp8Q@2A^{$ala$X80Sh1Wv)aozmau#?1 zKgL^-yaf^teqWN0rYsln@0pZ}`zG)$z)SP-exQ5V7mWNQl}xHuXv#yO9x&1_;H%|J z*_|8Uj00~=Xc9KHm|wh_G*neP%X)5rlZ|UZY7>rj><~wZ#G&e|Nh(>up*99*_hoS= z?!(pW9{OcwchSf0cuXR@NQ=!_AzU3l9Hs^v65UYY;4PkC5uwld83fHlevNcjWk+4+ zlo}PDzqOiIWS!RHPj*%8Ziq@)8jHVA;&yZXkYzQ*e~d%>5?7`eVphn|yiz$EXisc% z8U^_jMrj}ev&tbv3YwP1@L{**SF%N&>uI$Cflfg3G;qfe3}3Q)q1TtSs|w=!aBtmZ z(pd5m0xZTocMNd}As%jlTaD&QSI(jJ@bd@yjY@Cu*_> zMEXbdC*Ou_p$6Wlw>RSDG)|f|FVq;A-mxlSK6=wu_kjL&l8)0b%sZOzv|`f3k^bcH zqR(1dKm8`5ZxZ2qreiabE?RzfIg6E#z4yc+6*=1*Z&;7tiqM8oc5+x_hrRl&>!;|u zV2>7pGw;S-BrSneDxBWMbJjCHqWomw)5tZE8KS%(n^c<`FCZzSI<+QruU^@37 z)*!=L)d3T?s?J0ac4<#D8=srg5+c0u%r^gZ$rg=-*g3v9)nh(l@X&{+ALZ z{U_Fopphanl%T3yDMu{hj&7|UKyU6a+g@L_=Qq7RB zMr?kwmt3I+W{uMcETeUMrAvNzd-*A0qZZm9#bUI8P(PP|%1QGfkYJ$xi>^bgHjlDL zY#i)P6z-rG*ARv3!Ea=Fp(Cf{ctNoKim0=fwSKWecXfl(20{R5MzFF_K2k|dkS+^O zmmp@?zwH+p{EZ(Lnxe+b>AGuyKn94T_y~;IjSl3sjhSwl{f`5htc-=R`Ujd_7_+ZV zxHQJuYY%Gj;+G&KrJj7EI7g%|$U7eXX(Eb4P5G_B^?szIf(*1{R0X1Z;yFX{ZFTa_ zUo!i53W4Z9s{asNhS${_Zq**m^?dkOp5Fsfc?hqsddsB0ogjU3CFH4P)gD|KO!0yI zBe?2NYk>P-@N4|9;79y7_?_IXjQ<7w?bJ(~4FHgQA7Xi_kNF8oj% z(T$AXDnp$gF{kqr*R^6lBj8D)ybQJ>Rv0T#t{8Ay$gkEWJWo4^t~88G%bDybO*v49 z6lWEw)MIHJDpReMV+b^>Y+;wV%+#aYP3hbfvo?i75W7aTlk}JT0F6>}3q6WMA(d9- z4lht|Y8d4y{DrWh7)LbX?@Y^Za&vA@;ff7i)RBVaB6Z7>yzI6qKF+t%1==mI)!MW* z(Gd;MPGS{~o~BEvKc~F&pk6#g+LsE@Yb@WcHLNsy{}s;4U!g`c3Ae6I)Y(tUMcx#& zVRtzrkoIT4UVgg6N7(<-?2IwfHOcd=kit-kNZ_}V881a_c022D^eO0#L?6Z!nLq1e z{f40wmx(VieYly@d+gU(@b{z{{=)OJ8c#N07W5Al8yCa-G|2n0Ttct{hCXv}B$h4+ za85svXl&zlZj?D?cfjcRw8qQATDzOa$PTr+B)S5TavZ^J6wm$islCI!3%N*>zFxaZB6~OP z5VE2YrdBoC?Q>@=<^g*{Oj!VQ^%}_z6Hae-PsjREaEax3QY4bVy4He(7KiB_Nqv(+ z!kVOY+Q6VfAPIuH8fijbY;${_2KN3-0^HTpUtix9gM-BrzM6Ljxi9DdyK%PQo~)Hh zT3V&9@r`}hruwI)76JyU9;o-+gv!<$hICG3NT@PggF97NG+Oo6N|r%2pkdfSTpnk` zf&$)bqH1_s-FuCwBoGzlgora*QH#B0-GdlL6)(y*#*;t$QnG2AgqHu&|DnBZA5HA6 zklqUh{0Xs}(Dd+LZucg!;{_koqMgO*n>zw{HFO&We^wwN^GAQgv#_=J>eTRAkxNgg zl3fER@f%sQuhP1cU9GkawSih}iwFJ&`JClq>)Q=(Qy@-S%qKjdB}fT7XllpW+p_Q` zF1cBK+ECyTDw`$~8NSU7feo!m6^Z2@K1cfCyb0&jH;}vb6PHC`RC=JU9>Vwo+39O3 zuKUoQq2o6LwJiSlZ?_Eg*2Gya&8#n=3h^J0N+dqkHt-2#$G_}`3j#Es5p?IA+M)8OrP`m*5L(7I?k=#2Y{_J% zT(;Nrq*eN05on*QK~#(KU5_+S#I2aks-Na-d}GHG(2cg`btw3v$Bid2bC{4%`J&ZT zbI{C>nbu8y7xEJ!tuUEfGU)zpXQyAl!D_~ll^JW?l~lZUe=5uc#BCSE&^wpLW}yNvuQ}{^VU+jz##FjyP!570n~lh;SXD~pkX@;_r{Koa9H#seP(>f_v%>*l|^iJ zmsb*2Y+NLK2Vim!%Jr=RS7|XpLvzz&i77a>_AH35GL+S@ct1nXIZa*hN{ulN-0sSq zjV%`bey-t7g*1EhwZz*w!|4~Ltna`4A?Si%jrm`k+Wd8S|1(Z;|JxtxIv86y(*Gw~ z>HfLX{r}UKs&!Oy5ZH<{r@*)lkv)LTPYIfRf^|hlr52SE^c(q}?Op&Ji8QUJrCgsMNXzi{5uT?+J-O2a1ctN}(j0O- z%W?jh++>_uC|M8lils#T1FdVrpCsBlZfVsmS)RPMJEKkwzuo2Ubq;nfn6{hD6$7f8 zc+A)x$o-U02Fyu4A}Dq=vIZ%_Ou*LfcckAzQHJ+IkPoV+h`4FO=hTFXx1JN_wTd{x zMoEdL1g_^tePfX@%@Ov^=Z)v)4xG?OJ?MOzjk*?YF-DxCn-j>DgL?B7A( zB*cXk{$6|kwiM{U!8IUOLj45*fafwwUz@bS;_>t-hBVlW_h5JHkA}Cz=FT%1#>YhcAA&j+Y z){@yM^Uizjx?g+R?{|G?-jAo+nVxq*_%G4KNG3#=LB^1e!VLpHP7e|jPK)sUK&AOX z*y|4M97U$e%IpA>a&OOfS7iJ}mn@#;D|~NXmh-?{$94drJW}bMLpui&0Vtq$KVrxo zfK=SI{=glNHVE4^#K0ehDQVwS>2onS-ntRxvC7Awd3Nn^8WPfh+TeA!SxXB?%O~y})WF z>Wc~QtMkxEGQ>-5pdx_?Av}KO`_ZM#$`S*mihrAI8a6UaJ=qWeICnbF5Cy3a3JQIz z*tfQJnlz?7u=*dds7R3YAVUHJ7h!e~xfx{8214+v&>DnehNA*iaJL3NHhNV9CXH?u zQ3IG7xnw4c=`Z8ck0;CAd&Mi*@ zUGH)T`#=oh5MKIp`r)I+lOCb>STN86_=xrcxAyEm8+3TbLf=>QReYME%o}#R*28FS z(DreWARG3&g;{^GU(kYZ`$qu@b~x%B^t;yUe!YG1@D2Hxrp3XiG9(biIyDnX8W1x2 zVF|($Zvg+aAzlTC4ptIW&9H+#V`YrGdJZTGLhUi`LFOmgnMUM^zbhsk@RKhgDjX6& zj%oo@VFH~Ow1t{?ZaUYJT+F}fge#b%Gt8I0CJ@{h_G zM5|G|XhnpouA;7=Vc%i=h$M$QgZ|vJJsJPSlzy&uzIOg1vXeSWAJe%)m=w}PV(zf{Ehs*%BV#hnv_stE24+&aOfFuk|Lhol3 zFIbHuV;X{q|7#vrQUJOhZ5bf5Po)m^0tAX5j2%)Y&=L6442rFfr_H0IA8rnD$A1<& zAP$L2Q0M{4a0s+sC<_^KKM`!&d*47MT|yCCJnEXn`pJOeXAc2G&-;+&upQ3pJ&Smpe-8IK2cchn9) z*F5G40FuF23W}-!f)R3LfVkd><{PS^V;xEreC5bl9ob7(t$wx|!4oq1K66&g<{&z5 z!03UN7d9`HZiFh3>(-+SqBn$Z;O*8HoT}eXPwa-I4(0&nH0U(QK=8Xh*B-+j&6ebL zkgG7Ue5jd-Q>Z6nc$!3(gx0Su{w+yvkqbf>WGHcx1pM)sL+J<-dvW(7g9VQTn+1sl zWd*j=z=Vc``h-S>IE97;xpMJxDf83?nBvM`vq`*(%i|bEvJNEaVmSgjGCQI+#JWVT ziF}I86e?)8zi>$tf95L4low_dZ-XKd@x42)R7IuwKb9bwnf@ zUpk?r*d&ik)-nG`Wtu5Nn>orv)NsD738KlmsjKJC!$JY0`Mc+ys96MQaCgw=fm$uHm zNyAGCN|BIhN^MB-W@@C5WMZUWv3To=G8(28r&lvtvYxZCu@ac_PIj%l*FdZX=*R2V z&+K;%drDGI3Qvlpd`sa`=}@t%6s**!d|Oen)IB#}SzcMS4r7JSq{;lodf8G|U1=R+ zU3`howKOv=qu1JBV~D1oG)l2ob|&9?p?s14^!n8N6pQPGJAfB~i;b%j!%C3N?eY8M zzOa|0gVTh|#2T@rVPkzI{aowR%NyQVYA&ta5PP)Cq26(?)5@v+@|Ppt zamQHm`eS8gXXaYo}x=H@x=+%#85?uGB#7tdrOOQtgw01g^~0>%t(2|fz33fc?H2s;U131^Am0-KxZMG2aSgvQ8t zjJAa+bFxPNIkY2m2EiIe5hn6mCA2554GtZGEp})O9A2x()(3PXw7#$qNtlsXO^g?k zF**zFnHe)9CsoJKKju-2Q&nmA^-XJ(^_>R0!>^;Xv7MNX>y4-yo`kQ z$_B?T^9QD}y;()MB;poQWTfOIwzBwXNbLHTL0925sFCD5Sw<}7dJDtje-azX333Zq zgPDHo!4i=&8mmrV%8-<1FvU&CRR6j>ZfHAiqj&S^V(HT9Ve>`*QqOSRsA$S@x_($b z?f%~L-T1pVXiA>o4HXlKqvFw9)mRmtdf!mM1I~RDFxIPbNaHT@P`*dj$M`e!6lM_-!wd}?PQ!F?~O(u3AUtN36jMz#m2?DDGsSR zf0j>I?{uM3i)k%2uUfngVE1A7A~LDHRj;&)>nrS(SI_J#&sXPGld9Z1T_!dnjp>Xt zSL9bDR-98pQ`u_RbbAdxQX`@waFRchJuBfWQk1%P`!?;I3wK94q(d@)v3YOMta*7# z-lY7om^^E!9;$xT%(anRbNOT&v1QqOY)!TK>JVxxbTplsNx^>3$k2xDOj#{xPT1Jl zMs;nyhFM!wGu3T1uASLg@Yc&U+P(jve6z)e=9=@0v#+~~8_us7Y#Jne6#t0&^BEEq zGBZ*%67wTpEF-fk1A)Mqz2hKlynfC54FH6nM;Kpcg++VRk(Ytg})|ExpyvNn# zJ^h?^p4QrQa7Kq6)9Gr;{pd9jvx^?L^ThpjjC76gMt!dlGG$qBSI`K%!L8%Cv$T+*dSMgsIeI6$%GD%Pb_U^V{Q|u;^ir&6pkn!( zQm`AVNtj4W1E~J?p#dPF=77Ix8sKjN1Hk^<007WD(0||Q%>(;)Kjoi?o+(>Ae+MQ@ z2n#5=fm~|CxM>Z0=el<$s3cfh)y2gZZzmgF46*kAVvy^DhEH>VG!thBOXAOm0nb2t zE<{Q|QxFsawT4y&Bf&yJi2(+*TZY;}P(V(ZJ6#Zc=W?++5K2*fGx?L5tg@kf`RH=2 zU70TX=c(KM{&V%M+x;v3brzl!l^X)opWY&Cwp2J%jB+;?i8C5i0j}}oMptr}@who? zL1I8DD_+vGAfIcf{?}ED-|F^0CcQTU)`R>A2FPKk+%F6}8GuWJZ2%}j$l{IdomJAG zlgD{nXE_jzGPN5vW@f1j1;y4d%O+HoKYKxmV9?7I3A0jr9OmKSZ<_KzM94rUX3?3! zgLf`J&wRHkjtLJT{e7m;s#>#Dw-^Di7hw?8O~H_BYj_|*wxA++E=Tlj%) z6Q{3b8?po|h|cfqraZAnXA42Cew%&Q*3VG0qPdgG{C~6{o?v2k8{mPkH*9Qdt1D(3 zB3Tx@{w+Sr!>Nx`%hNwF?3iEX{j$&Y-hVzUX~pM|iiMo_>>`b|e6N4Hw0osjBzE!?8oYhto}N{P7hseEQkOj?a{& z%$y9NKnsMvfzk}nU7_g315)(5V@LO!grHXRGG9X8{lQGz-%8@)%>5Ad-F8&u_;bG7)A&hqMg zf^cb9_pL2WxH=-utH51qpyrDndgTBH1NwWl&zCCm^gZ`bnwA=xvY>jO23#8Cr%Ue_ z)vuH5yqS|F0ZV1Ytt5y$%|5i;ULK?uQ+SOJH4*(Iww?})T8N^+-fmJiNTrT(on|yw zWB&n+xU;9eQN9qxo+<{-f9CUn6R&*T)X*4OAe`JgD+`l)%dJevgN73?e?<=LrT_c# zATI{VOvyHwEmC6;S9L%e zEl=}n;8y?)MVhImJ51#ACj`+d5tbQT(;Ga~REzzu7I{%f_WaEDkyd?>P3yLv^z$5P zAt#EB)z#MaI~w_R>}2>)J;xj9*wCsf=ta9v-UqdQ7+;sL`yDgpjciH!Djbp{%t%t? zQPP=Lz!ACd?LyV?mm(v+ZVYCDua-da9yDAM_-9H=3fa(kS7%ew7owjYUZ#ZY*)_Wbl*GqEsif^{7<#KZHiimk%~!QQXL0c)@` z55YX~H{n11_zIf$V1HybBR#lMJ-Y11_gr1J6i2hEu1Q7y0yLY<^WMMmsP~~!Z zSnLQ~Pv!IM-N5k7pJe`4WR3?VB_Aa9fTQoX4W-6Jb*Ee~$DqJ|58LE`Y5ue~cjdYO z&(od#-djhGdv<~ls%xL-_Bxz@XvuadwBPqH3&`r*@-iDcmUyDTHeN zF0k2SEhEe9h3E$4vC|d2R}b*ma3SRhE3Hc65+% zWp}bzJ(}Lkq9~M4pDTkNK==3-7$#|7o5UI-|D8{~UNdo3O!wc`rk&e=mC-7n>o}iu# zwf%WwQgYDDuD_FZpw&|qM}cOVa9QDhfH~>wKtrws&M{ZRqKc9(iFYg0H@7xT(Q9cW zQ;dLe^v9wnA?ME0(}jd78w1`mJ&5zKHHT;Yy|5WHZO}15EFJT#YEUW3Unq}v(X?%4 z=Amn5Yyn>LZ;bV*#h&_)oyh~F*=r#bx^G&*+6Cwjm)FDJa{SR>G+Nn?hjNa5=xzKy zO&}^Q(w3Wp9~*0>0xCC#%+FF`OM1C#hFN=SzT8-`*%7$lMiog-03AOLqn~fycUm9V zt^6w^Gyyd;EHb}7@c^HBGB4%lE7dr0vfCeMj0kq{kc72Y(ILKvD%Nu?5BhlybSdvI z+&U+$Gow$2g+bP$(V=nZ)?mg?Jli6x&sL|eQYkgS)EtxPwE4aYOV++!0$1AZqF2+X z#z@Z}@txDhO59NDMAO5LQ@SX9`fdu5TPTx3q&651(wYVK9Y}ao_j8%-)V(36sv^N* zS&wOg8&G~VBTEa)jM}=&6KD(efYBPtUH{&%M5h$iEc-jIs4Y&LsD5)GrYxl28q(r{ zqa=tQx@=1~haK+xm^siHwvTrkH^+_zcP^(3fv2(B$Gt*d+R z27a{`y+7O}Q4+{f@zKMBgmyr@*f1Uk=@WJ0!=p(=eJ^+3yNMSbCc#AYy$OK-gx5xT znT|~&?{fRsQ(_JYspdhtOt1@+kBICH2MI2g?K)w zlW}@5&6rW$z*C)>4&o-8@7^lHM~w6iqDTf~PaR$a$XkE{H z)D=4vO<6oEUUC>*6hk;eC(-`cs$s+R6#~YA?fOi(j)JPz7=f6uFI$`)qETST$9cJ8jFyHTo+~awLrmU1m`4RlE&zAP`^BDAjWo%e@-DP^IY*bLEhrxKo5M%}j}_i&S# zc|hliGVk=UXUD{@?F8LHCa}vq&`2{5r6%ecVgPB=pP_G5!Cs`(F{?OBv)<>abWjsw zWpzQjuT#sp{&Zr9`}6+5bP^MK{+|2|r_jlR*#|TwgAayY+NL)6UOJ7y&RUk4WPo>s zls;hHO8XmOjXlJteXNKMq{Z|P0colifyRsFH@VH-$YRoKY7s?Y5a_9}uS&mNm7${S zDEdJGX5=J^%suh0pwAO@v($H23N-Ag;lXobrxxvexf|yd!`6fytpSdo1Wa$+%>jC# z?=wuKrI$a0u={7Li{}P{u%{rJDf@rFHcD5K!)q>u2q1g@P}J}GG7ilw40mUT9QWAJ z0R389SvpLm)U9u-!>7XTJi)9Zwf_vK^&-bwtal>mx zuKv@~!hge*cVpc~L$AlWGO^u(e|CL+ok;4)%BjQ9M1Pe*bz|yD(QrS(4jg@7 z54+eA0Lsw}E`&$4p<2W4-&?GKQisv>V0Uv{V*R#+HoR8Q{wg!w?trFC%I-S(s%k9X zA?IAA@`_(?$c@DXO`34F{_Yv-X0-G%Tqec^OmouH;V3zEL-|T$tAn8*FEsPk->LZo zd5ZC_$NH6S+;yT~+cRa8(JFu{0MsdB42$x66d?=c=`Vd-=kIs6)s zt{DAVSGw==Zy6j-n|3j*aqle0o!=BXS755*ju|$9eaFDUMbCOLl~R8i9H6pkTUrJmd*UcK;bGXE_JLu-*C zb>H~6VP~O|z(hf@&5R|8m$9_>NcTtgbsakoc=JG~J4F2}v5w#C6hSW|Wr&GMb(~Sc zxoe&KT#L<$)=y=l9thp%xsExpwO1cs8sQsl<{(Ds-%~+3dDL}%7{q+Rv$hV^akJnV zCDUWB+S-XG{*Mb3=!8o+2)kQ&Foydu?cnqRvi|!mT2JoXs?Z}XukQgI8eIwl8W6O} zcj|sFzdJ2PSn3(sbpl+5E`1>`{X_RqBsP@_wA>l_Q`0u1>H!87d}*?B6V2+cHI*>nXPo4 zCJyp8R+1T3kjn1Cv_O5vO^Z*h1%1qP?Y0(^L*H}?a*PDy#I^pk+)gCq%(nyM7f_4S z_5F;CpthWK9WNBV{vy!zrpN*)U!=F6 zY3JpfGm)@C4sZ%>Ke=eqmq*gt)OX2oc&WW&Z50s{Q&=j|oefQmBUiCPb82(r6vg9W zO@N|^n7Tv z&`9UF2R!{;sG7JwZ4ZJaOra$MOTFbL5cr4E**QDP zJbaA_-~(dkL7~I}La%7uPPIqm!vN}Y#~8M*2&Tv>@jNOs+DbmZPp?Yp>>B|=(a!c; z>Wrv*-?ebs1ncD>s4q#_&mEa+SHvwI-Y zI_CZhM}1nVBS!um5l%uOU1*15>7rS5(z6zz`SBCodeQ54cqcBkvMH8v*ZrF@(@*u(WMdbH>; z))3aqe3DwS`rL%0(&r*`ww49yY{c*3aatT!D%xq)fWVHg3?n9u zd#=7~F+&1WB9zOIBDb^EG6=wwwpZvex#%^MQcefzd)Z@cU&8Og`)IL#`gfnEfWeR` z!cGR(@jl?_?}l+18jpvXsY_R*bArXkQvSsjxfg{80o-+K=vtZc4{V5D!mzZcQAr}2 zd;F^AJ21uw^28(I{NM>o%cx;rvz8t;p4Zx}+w06}F???yTEDMqDGzgCsa7vvqu;mV zM9c2wBcB#)xe3@5HK+@!AXwX$08AI<*Y6$@KE@EW3hsRnOY#S~+jt1NxzVE7FQ}1T zoccSYq{q#yYy@f2ddaDipzq5&;zM2dIk#3EB~&@H>|BV1p0@ACo{ofznNp=tc_Y3I zsU&|R?O>$ePm@}~)l;PzuIXu)hNQCwZbZUZJHd@8_z!?cbJGnXbRG5!C#)SrUA!QQ z8-jjkpFsqU1a8#4;|r~^CWa*f53cmwOINMBAT0Ch6>fRPo1{xf>U+Jhx4Pg%2$egU zAvk|E*Fw!RoZty{kL-A+y2?GFl)I@xsj0Do$3F%`&jisE1~3=KXL(qFUWfywXG5?^ z-TZ^2YVLw!?Fm@Bq32q`@|mUtmu&WneolnUJDufWtrh4hJV)fE@HxmRXebeh9eey55)!gUXgdmR5=;1kjR3TC zivsm=f0~8xX|UD#CA<}nvWiCa56TiktSB0n-NjPGkSEzcb96F7K(r#gZHKx zMeU^IYLbY_TLIzlL$Xc;4<_$9=r1;Ye;7=y5}9+gJ$?4jZY|A`Z3D2#@cJQf(fNnTuC9V8N=Nh_ zbxWGW0Tr?iL3W1wXYTpXz8uo~04~q`Ty>bMi`6t3+X-wH?2~A5n*jgEk#MXGNfX-9 zDmey8^LfdPo50)PH;>+CQoCl&=Rd!e9-&e3qY$SBVrA4PZ@;$! zhdK+@Zcv$9K7&FN*NpngO#*O~YRw-YF~WRc2V36pTDlednUK)-K? zJMXlgeAr8JrYT&uv-$#M4dj(M1b>LDitZb=7*Kmr96NWDplF3EqbYVJlY?`02HYJAYA1)dvq&d`S>VKO$B(&3A;o3z=s- z_&6=RTFCS9VR@OVCZRV3YV1!CRl(5qz!|1@;1?c$qSb-?^(Tg8Iw0*bs zV`4-K!edlcz_81KkOJ$KQ>Mv@pzphV0cE#>fIjAdCXIjmhsPDn9wIKta^8o#Q9WN) z#7%~9(Cl-%fm;d7@cJ>bE)W(TeuN>SEss&R0-EBdTNd>4dL`gp2381|)u=4kFQJLs z22JtTt;57g*KZ6ryamz5{VYl_ zcm&lhd^3o6{x+tVKQA#@rmOf5Zw~jZp7?=~6|M)e64@7DyI?l0qM5jc2JjEpK3?h{ ze!v4A^QM^{uZV<$Cv#M(YYeiEVTb#Y2>Ums9&N63MKFEObb}!t_j;_PA)Ew_f#{X1 z`%B4Pg@^e17r$>X+P_~j@&dyy#f`t~&eyMk#z6W;nD47G?&(A!dLhvFtDk)L;QO7y zsf0l>4r&A9tH2SG3S?WW)8`$5lHqSU0kaE-OvGHSZSX^eYy0+I*rD&G2Z7Waykf<_w3swBTSaICoT2 zOZPaaS~*tn45<`*I6ISjIAWRy5kNkh`C94hQL5@S8)&v;IL&<2)V?~VH&}lBiEewk z8RIiIGfPvtuH;iHOjG4Q#kFdlm*KD-y?xMPR`M~{%rofEeO()hxx*P3Wpv15^`Oy- z=;-KJ$JPP=)x;|3{$tM|Rjh%$2SX9rq5gR6mf4HLg6Xuv@mT}-1;QN#Ho4a(x&F_G zDhUx8;Tl1`fPek2g08}BNDct#{B8e-Dm^DNV{2pjf1MfssmQ)mm$cnv#qC90b0u`L zHC|Ua19y&CtKY1a#v!o@#WxR6S(7W^Uy$&^**Ne68SKyxMPIWH)z|dLSSx;GUgxyJ zo2#ws#ZRHkoGFxUMW{w(mH7C)hLU)_OCAi%_a-L!ZNKS2w?ZRq5c|fAu(5I}@Fh4Y zsIa#-8Z}yEEgjZWQ|0^8Z`@TPh=L6MP_H#;O|3+w-e`T=|1$;CUC_Xdb)R?uwuHFO z+aJ--cId*Ry2U^&Z3H929^A?{T6F1$SzJTYO6im*e2)R?B1CMsHhp55qLG^Ktc35O zuuD4sTUs-1+`)Yy2!|4eff|+DT#Lo}Xu~S~CMmL_q!~+x&lBYdEU0g7&V0C@8Vcvf z(OL0yf-lc;Z`k>x$99h5-6UY`zE8mvWb>jmYbL1_aw0UctCOX5rD~t$GaBOEqIA(- zmHK4_epjon)q;9D+5=)YYj0cRg9~T->KDZI%ndc%%V+U&vI%;wzo6(rH-r=R?9ZR1 zMnmf?Ke`}pR+vFdC^RQ)vUpV{9cTxh+fKj;;pkMDMJ*EIke>jn!%+wj(hxwFfM)X7 z1aiz21$A+c0I~{e?<~Etuo+w4z9#q5rf46;!r{MOZVYPWEq+U3i8jK zO$d%_t!pF|#K8rgWQX6T+GDm3J-3m>!sSh|Lph&*v_nxw%(JSBlDahuE^rKij7koA zhoU&QZ1hM6&SepvCe||~gYPYSWYr;)+0XA$cXJlp+DCH*^hD2g+6z^BeO?xR$xrS8 z$kQxLdgSQ`r(2KdFnPV-I`7HwM>oM?_q`o`cC&VekGiUIW_w9zJL;+lnwVJU7Zjhv zezsJSMQz2Yf2HWGPHnbGlP z2=dLy<)QsEc)X@+<<={Wu|bJV?0$2Y5P8sdqYZNgxc!#jN1wb*l6-!B%xJKOpwrsrFRgJC(G@=1zxbo+X8$3eT1l0+&{ z3{K%rlvEq|&NVq=yT&2%H}XMH&^WVUA&53B>h8f!WVCnjOQRxq6)UI{-(AI@U~r0- zI}(*Ud7R-WM%Ft)3xO+-qzG=-aP0sjUbl$XC{&7 zR}0yuK9$nI6#oT!vn?ezD;I9O8@w=Hs%LlbaJPKrB;9s)@NCTtd&)}RbF?K5l2r0c3#1;{go4B_` zgE6BW6bCUWP0mQyF=+WOJM0yXSd6cSq|8?tI>P2|600mJHK1vxxP%s8dRtN2&h4-L z3k*|(K9dATFZ|yPA}Kirx94paXcL**CR00$9T#Z+9uTSJg9q9wZWFAe_#8^0uBE=( z0-qa=N!njf|F|0>je;PWzs1{|c>gDN^B+awjQ(_Nt~r`?%^#oCRH-8I2f? zf`WqCox}Va1%+8FA{Q>q(E--!P#`o!FqO>@(qb}tQV1nS`=*Ba)}VldNT~&prA6HS zS=KP9NKK(Z^iQ?WKodW@cSeXGqZsd~@S(y?6fx?mNYM%(${plYoDn-h?y%EyMP=Z~U*Lu22rYV8hKz%ZC+*sDlk@8upOKa^GH5!Ok9=~dfj&t?W!;xs-q7LJx(aeB zVR166)iJ7zlR1*9FA1zjmsT^B*L1m8pQR87Ur^nLmwwniaI(_5_z`^t@hT1J zJE8ErR$w)HyV{1?+u^KlN*FvmC1`GoQ!A>Z-EDpk@8ldRn{E6%Q)c(p}jO2XD@8T8%wos zbYcv;K$}E8;w4+>U-wjh3!eDlp#B>8TDYZ-G#8pxD(>FMu*bJRh5oUQi(9mMn`pEM z6aJV!*@Utr>P%T$EYtiwZ}h`tB%if6*;ApMT~8KLe))C>`iyX{eJ4jO z?9QZCp^(gRi$=F+p=|d6jle4zAF}$(eS=??;Jo-*amP70h`F)=woh&R~i;u_9uZ^@ zI7JB8N;se{(DXJBbuyab9Z7L$t0_3+{9;BqDeIa1G%jlpX2SMrKH$kntI{%-!aex$7`ZKcew0y< zc@jl>3}l5xOW#V|`J}Ry$S?+6pmBev;99)L3Ig@PO>pZ#;OR%@Vim}Czz@Ga?TR=M zSw!1`c?1~$UaJYi_f1PKND4*yP5%G-I>+e9*6!QKwr$&;q+{EuIO*87JGPw;JGRxa zZQFLozB%vz9ryG(7pp$ihq<0zReSFmV?T5KCZRedguPsyW1i_76+>!fyi=Z;uyI^P z>boWVj_@3I9RmZKtQ}BLmrY6F(A{AmsD5=y?Swxz{NP#xMk`8#!BuhcJ#pOtn{>=8 zLWIqauQ!VpgandTQ_;DMaa2F;6E6y<3gjWZTvOFAZwg59cC!Ugmtjvd_we_62}AhD z$e?9|8kd?<7tuc6uM!JY5Sx+pG(OG*%w@LIhzf^gs{&4o1%wj1((-bZ0I?eNfSKINyxubJqI+q`Y#*frRoC`D zwH@XQDGYh+Ngzgd6&yx~MAopx8j;iTdQ$m3It}Tu23VI6JTqVRbn)!065SGvZpW}RwsATny&Y#(C64wA? zfQGhUX0rQ8&X_#Q{^JfwnYO0tVjFKJbmeW;8Z#h!yhzKZ_v8J(b-M{v+Q$K<131AX zC|RdmE?CZ0*Ju;Y6d9NX0QjmCB3YA1ZtYRFNORLtBD`Fi=83xZ3WO9RO@2@lCU ziBO41pX+#2=$F^8%?w8vW~lWj4tD2Dj68k3Gb@>^?HU@o5??uZZtsMh)zYP`*(q^O z>`ENhEt*^{c~$Mm*KKiav^y$>%qG=K{Z;7Sbx^U7@Vxs|!Uu4saIKdUo12^Ed0hxL zsi}s6j4y@dU0gGq7F^xjHV4>HqT-r->*UQDc5$Bx&Nck6Q$GEpIhsnS!yI#M4tgmG zVtmI-9o?#t14&cq*PM0C)?O&pw+t-FT?yM0P~ZYWMdFPRW4Qz0R7jqDYKf%CW=XP0 z`H4{uJf?(x=9n~A>V$MY^-Ee>V64ezXf z(U_6Rw>|1yzi1xH>@SI@+0ZcH@F4{kRDLkdlH8bXDg{#8PMsb5%|YX%odHF?#Sx4^ zmpc6Gjs>r-jjK=Nulkhwn7QP+gfb45d*Gy)4P^%#j{A1xB|bwAd%s;5MKIx0^dxw4 zpWBCxv)O_B36LpgK%bC)oGpVV8Twxh9e9r{fMM>OZvLq0K!4M#{OLO1s`5s^*@GBo z%6wH}9|xo-AdSR3f$y!{Krdc7THjC~20>mHmZ4>-yVz>vw>`$?2fY}^yD+AT%u(e$ zWVn;}?hNz;_6GAD7cuO7YiEk7i*IxobzFEPe7P;{#yBZbk&SVb2pFg{EvUMChkYZi zkW{zkNG;Ad&c0SUe0uhEdnbw6Kngh`vs)wK5@Cd61fT+ukbRM+uc*_KaK97h*nhn< zXJAm^+B$e7RZm`KJmCNA|LX7Q;0B||o^9W>Y$>H8gJwUYHS+*7_uHsqA}ULj^1(l< zn`6Hk4xFzO{eXP)G8}VQzR^(pPW4SS27(JAT$;evD%X z+v8a+@P4oVb>K1Su9Gus{BTIR&Vy*zWE5xUIWk)^x_{t~wzrNHJANvWajE4Vjwe=a z<8x;H0C2&6a7<4}0mq`w`4~YX&%v8Vil4cb*=bGboNwb~YD`5=`9*nh^sL9gl1zeC zZ??(^FrOekUpP8@LVliVoW74+jA+m&zvaSl(f*JsFx4$KCBv$Y#&HnqV0ASQ zwEK2;>>kn7avXLnlVYZ7L@sPMMOwFi^l~n1n6vKVEF5Kzne5mdJwMuK!Fv9zI4JU> zr}oQKLi8oCXh|&CG+Oz=W=dJYn-fH=-}5}L#W1Y1-b2eIU!KbpXJ%zewq!Xq+PQm{NIAd6f0FCQR(B4$;7 z7wDWHm+n#wV!>mA5#>Qu^r8x`)`aP+TPwXL-|^1}Y>i9+g0B7K2YfGscIXCyiq8?~ z7hVw@%`eI{1}BDY6qT;DPKLFpX@!}6mLwFWwmB5+2r+I4<-qPXArfG3Iwu5L_j}%L z*Pyv>vXqqU+GP%s(m(a>oHXzqh&;%nM89MBRJ zPe-I{vF?&<1v$$>MZMLn#LsYK^pSg^g-q>=`9{2a_|2Pi_^bm%FRHw4f6aD2j7{jG zHr`Hgfr6nc?zJ`LK;z6m@g+ve*1HSh71q37?#i0-;FT;X>#N`Koc8AY3 zz=#s20J&1@^fNPWQ<3+Dm{;G0vyt&>GT4I%kddV}BckE9DCM2?LY6qEf}tWXNL+wM z1K3_fQoB6#Xi)TE8CIy#F8N6P_8SRU_LP7Ms3s48tV_)+LDI?`~`vmrgybJ7l zU?nKf~|S}noO|_NqEA$ zs$97&rXa9YHZXC3Qwe*um@~;j!?3hl_F!ODi#vSBC<0z zw^Z|TS6NQ>W2j6e?efyLwci2Y- z-)JUQIBlrnL;TBz{zJ~Ca<+Qf(=aGnjl2$j1v#l|T1bIS56%U`mj>fJM*SPBLkyZZ zFLqNqVB`$K(`-Y>>noX6;Q`N?uaMzd2$s34{f#;;{SAQqm5eav^0(`YxE%o{-~q)` z**Ll)wCV-0J)Fu`O3Irj0c6ddfqHe{Y=*bx_2khByd(2+TBEryhA{H$QXPmEL3{o( zptK^M{>rVGJ){I-e>_I<>mpVw{r#_xC?@e;&!~rBOYO+FXu2E0AMP%cSBsmj*3m?F zzdlZ>?>$&8&psZjO5J&NhHhjQmu$C^4MX=lSiwL$8O%k+U(ix}sKC^LXW6H;N-q1_ zv~>v7&~R7qhXHH{yxagvY`y4n?gZ%Oh=VV(TS13wm&TkfnH&}Ij}Ogy8ebrA9XJvb zzc2Wd&u?4KxRO0lj-d19cHo5awo{j)NNegi^he#CTa6*fEi7niR?{Jg3@ z=rCfILo_VZ^LkmRx4KIREz$E5z<9Dbw4%v>{F?d3_S;KK(rdQDytc|C)%gvbe&OoEkyH70nv|`+ z(0acGDR?Mll=!z&*H4LumiP9gOS!uXH7U!6MiK3|htNv#6Yhwc zcQ=PK7%@ycHp9hXpN~dE^vTYQ?Y_pByURE=JrG^n2JC#>DM@g};lMlfj@1vDerZr0 zpox~ME~MPqHKg0Ts0$!PZR)iKETPKw;fx19xEjzPaL~bt>^55DeOYOfX_d~$0LKKc zQSnW!Lo~u#p2ZuRs!HvHs@1ias-Xp)0d>BE{g=@JDAMrW_2Js3RbfAfT)Bqaw$jxv z2cH)mVQ_Mpqq2mF?BRMik4|z>l6!9Wm9g*P+p`6vm(t)oRYK{}t_>4Um+Y6&P^(@N zLHGTpaVtqHR-GoKHtYd_Jh^Sx`2 z%#clNC+UHBi$PVSgJFAM_pCaIFn4j-HbdA=2&6DL3GQ}FD+pA1O1MSCA!-Av%ymR$ zojAAGNo%+3A6J8j;`xQ$EIG9>R4Gz{ZL)>-Nm#Bgn>pCK)(}ELUbU4|Cl;3GVx=uU zn7}Wqt$Ss!(mX){CP2FLo7j@&55B-cv`AqbOW1GPi;TVU4-^{L?E&iPOcUA zT&E>82L@b4c*M+<5^ICN`LfO$i2!qvcD2OUzPNP@e#TL3*Dvukvt~jmKGRc?gEM}UwK}9`~J)HrX653FAy5Nnt?@b5X z)U4oG-DxJ&RzTIx-}RUc_lWAn-eZy(n0UNf6PR~`TF(c7t0c9`8qrl#BS|S}uz-zU z2hOuKl1w~(54YdyGSmyiA{8xGVx#&s@U9tSEjxfB7gLlcUVsN{K28+wMv9(%p!5#Y z#FTH{7g@Q5(sMjpu&j*2<0f-Sv<@pz9(|rG9zqg{DPBT*EE5{Is+JPx+;wUsXGG<` zRg*6Fe|Hdh^V+bHX3bEI;~2gd5!s_iYFv7A!j{37ljQcwcNnH`!QIBiXQ53p()R)z3$;$^BvwHc3oMKN>#;igv4#1aKAPGx0DhrV|Ed z6&@;q#~t_^+wju;=1eC}##n8bYVn+W~#2BAM)jSq=92u@XC0?n@cDexp)Iodr z;f1wb0ZY28OsI~9c?6%kdCbi)iRYd=GDdEtJ(Lh4Oy){c2$oHhVb7<}niu?R=3Dmw zTJo@i&@u;>v`IIT_fn!2<+ytZ1nq>LU|{E3w64A6Zw$E*_l&a@iJ+)K&;b0bj*7CO zt@VYa(u(5w=GyY_*0YR}qJtZLN3YN9C?||{j>41}wHe|09D&iMPb|~AbP%}EujzzM z2>Nd;fae4IMllKPh7cdJD<=gz4TOxchM7~t=rlA>%5K2{PZokMaQM{Ym_w{&0&g8 z`JX2W)!0kVq)4vEl8_HAlqlcl&sCxI|*=j zs|e=uPp+jI9&yJxB9luWQOu$x@-{pW+7(@`uTSN{G57|H5o=x6;wz&W$sj@!d6LS_ zq|+LeFbZ|?MPljDX)m%GZQfSv)vn7EJThlfAensqLE$oP1gEp`@)+>^sruy-J!8Ko zgIKl`aiPR!vIiVaFuPj0|t} z;|yM->v`HX$mQ~#iAR8w6-m?}_`;t&gcNV`V<@T;6ItlAPwIi_;uzlA+ykiH2jIy z&L*;^$)UPz2yZ{lS}X=?eR7OrT$np9zpD5Rn;Sj?Z8oO~Ox~bHUS@3p)(dP#XDBAq z%?c&sQ0K#L@c|40NjRPw2PZVhwCs*dYxI>0l9x{d7`rUY1hh*XLhm3~$GjCi;HRp# zkJ3hGnrgc(0IdWcFFLPOsL4R=!`^$!=x4jn7rJ& zh^3u#6QP*1@Q`f&hHUIWsIG_@Nx^73r`6qHSBW4zj~5DEwAHMdD!F$4b?Mgy9VXSh ze&lBcas!E4n@PG7$}}2xBsu`&znO8uzPnK)g>qTN+_Jc}Z6-)m#wy6H+QK1GdT(I{ zm-=Nt+!ciCIP5iFQgB|t1U6DCj`X!OO8Ux9DG6(y6{x_rI%3oGM;mX2OW3lWMt+yt zgJ=Fw{y;-w6Ja~h(w1?3cF0E@YU%i)`3d3_TL&qAQYNp3lZshUFce$axmS5yt+qz< z;#IGRAIdjF$`U2_x#KzG)B%=LHT$|koXmZqM?qr!0M5A9f><$F#3e=Q0qO6VRWcoc z{6RPyiUje5m_UBTiwaLM&1sHJ8uoc|eQxiM(;JIIx^v1a3t4WNgU2Inn>a9%!T83N zmuBYASx}`Xy-)@j;fAgk*->X;EAPB@VOHO*-`6zBT4`W`6Fc*=O}UxS;=a0$TW70n zkO7jIOs<_hSJfKe%WvJKL%@~D>N~H)nDt%ccaCumWb3VKjxy>j;8l9rm~6!tOp7>1 z(@G5{mYciuNh|ly<5z-9WK~r?a+cXUwDuT1Ct(M6CUe%krSBqpfm2&J0^QLmljWy) zvM!3~H)oH?7S!Wo0_VpAiT61DA$`m&~u3^JqUgxW)S{)m>EkpC6v6QNL zI8r#R;?4s0Zz%dURMrw1@dmSioh@PtNuTqwBDj9t@^PczQXY9G5y%QhfTVq=sUME4 zz>q~?QFwpS0t|O05nT7mTi%Q1Xh<+sVQlFAPVLhmjlC)t&@2Y^t^=^%Zi9`w2XPW^ zQJ=*A%H~R)wvH@#+HNpTQ(REZuGDr4<{9irh<7?P`QF8;tYHU3V7Ys;aj&rZ2r^)! zIQ5>imMd$SH8XTMwXK?vYHC~2%$xxEYGP00X5g@NM% zC7P1cjc5*Mb@67y$+Vj#!LSm?9;>_|esR_f70j|LIC{8dRDPLW1VrX|`MJ$3aR+5%p@*0Qz$Uuh1b^Fry?ybQx#A(Y{?H&SNx% z7voZ0%#vhZ@e-VJY_tTlk?6?))3T%`17)LU&d;PLElO7esM05A@Xh%W_pJ8D`gLQ!~QNN?2}SC_(a0TCRpU1DfkJ zez qASOO6lxGP(Wedd1+PLi%6`UK>m^~(jyRF2K9IuP)pX9ec$*vO0RgQaU$Qh z?iVnKt8~9Xk6r~m$uY@MZu7GgI1zI7LwQ6Tn<2W%d(UG_dkBJ!_~0Rf3dFh^r$}F{n}h3F=o%Xw@z`25>s?_=wq=eo&61(}l0yDf%|9Q!L~Kt{ zR})FX#b@9~VJx-cEpQfrRZUNw^H#MRW_xy&sK$^u3-Q+~(=l{|258aEo~?v&C^42V zNprHIi}{L*Ag}u<-c25V&%VdN)-UCR$8MbVHZTKu=1xIiv<40ONmbbc+;5}l5M_H} z@+Z0n$TVQK6Gy*9FSS%>jvq5pG3yW0$wt6qb$6+6R*&!|*{^A3@G=PNU46C6-}x;f zzph!7uh4km7eq%>-5n{RAx*R$jf(2k$Zm$AfqjX4x)|Tfu_2bBssofE;hH#?eBGza z!RSQbEcJCLqV9Ee9Z18>7CtAZl!E67bH;xB*K*_YDwH;VdC`{gw80; zA(qUzQdd$!-=r1Se6k5+IdZdfC`FNq?pPiPT~W~n8|mH@K7Af8p14@A`;71m(~s$? z__&zh9P1G&BY7vPNUQ)R{C&3qF90pDn!ooL53D}Z*SDZuBBMjAh2`>R&|4@gS~?4D za~6EfRwR(YLI8_p+%S#_I#jx(6<-Y2#ZYVv$$I0Wko%N};e|UFQJmmyg4V5vKz{{W zOaH@f*>Ci2QtQG^dJ(D z=0*yX`Pz(S^v52C8Q9b>huvL;BV`sTkR9NBj6U@GZ!>OuT%*#}TsWyJ5#`_u@g8@_ zA%(MN!s&1{}ya~C! ztmG!wx&W|ii@o$DKZ=@}8M#~^BLsoX9)5B}CS`JFR2g{{Pb$L|@vqzqEr^t#Uo z{2DI7T3Oe$qb072o~Aqx>5QCjO`gqQ9WooP%4J;e1i@IMle#{%MVJw5 zAkYC~fa_=OlLC<2B3iT~FENzPe#}U#Lsxk^Jt^K*oD<3O>1FPNUWb_M zL4RjexzER_E)5y%6`mrU1XG{{I{Wp+!tQ$XOigiIObDX%E1=A>Et|u?`DY$v_clTv zm*gEL7&7D#w7&-c92dC@riy(-gb&S@pD0LQQX~wVODevuzS-73rV^vK15ayRv(BxsF(ax;iDUNk0LKI) z^%-GB6XBNmZT@X>Z&)i>u)wg5qh$s5RE_9|?+e|WtqtXMn+DY^hY@dw9UcSaY;Sk! zZ=y8y*3$Y&p_dc1ROCCVUMER7v6I=}X-4=5Zz2t&R~ zC8dLuxTJO4FvT7P&j}k_{ODS8J?;3e@5PO)a}?O_w9wp&r+J#kcdcp=qU5)74iC5eS}>=C9^Y|QF+O#&rZq+{@M zzd64Q4sqqHtngk&20@1>`C)+TdM$s_u20Y82tzm3rS?_63=A}KD1O^c0yZ2}xA#Xt zbG${1r)gU+djhk6WoHgJbG34hJJZ7X`oidl;*$Kz15UbnT*2v-!Ha-OT(zswCa`$V z#cCeg7{6+CaPS4}sxk7Ct1F&llPl+ee!7UCdCDMOH8J_|Avay% zeiFHH&|na6Yz0jUJV&aMa8F6V@elE7=D1cc&w7i=#mk4Jn856yjYTnHRIL@oi{8TC zl=&GL5SMz?#tIO$X2=XyAkOcu&MqIK%=q^;zo|~_Q&7j|6o{L*xr8Wnm8+a>Z^0wc z$9NFR$=^n3p1g82`A|Ax$|^8A@hM}1wjF*4LXkYS6E&E10#4h3n{sO{pT4}t3e6nr zmCj|%>zgF2f_$=H;r#(#oG2yQ_)J}1mvh&BFUO;fRwPxc@nJN~`|zitvCK>AQ@fV+ z_9RsR2}-h~8yj%D1bi{$`6*XZ+b6lJmy<`7r-NGimg0}5ZL~>f>9z|gvE9ZZneI(A zjK^7hSYA%(OUVlA*zsL@4qt?%M*cW`Enmd>&8h-=thcMm(0~y*IT{VQkU}7vj;6O%kUyh^#K4UY}3ak<+Ax>-9A*+{X z^i{(51*s&(tlK>jLd`6bz?$)NWPof)1 zh@}!Iy|IW}2RB{;_RieM{v4Y(=j@Mu>NBhsmKWQTVLW8zsR&(bf`Rj`H#jG8iGmv= zb3`H@%=nh>l;07@Shgm!in`2}@sTmpaN#aVmvQ9-;9IzKBV`jv3=1xe-4jH*>HG3h zN|k2{zbQk(;R2jHq+%1UrqWHq9h3@%T@=-__IK&-G)OPhbFGZ!@9#Y5+8KJH2a4XZ zKL1Gy$)7tE$9`^On#>!Obt+UGTV32fvpU+H zV@cWSbB^ix^T>hI29sNIcA(Niv>3wZLZJGYXQJVLTB2Xf3u1-TjzSWQU22M_2}x$2 zE$mKlVoi^Tt|s*P8|=)I9G<|%zHwDY8#=tW#}Pp~o(C3C0kj@YKdsIvN*LUXph&p4 zxm!ru0f3IJ0kd9tgPH+r7NPkm7p~KUfADI(|OE|EmEO9T{ zwqtl=A2SD9j8u`!Kw)jWethYd44s}!T5NS)uIC3S^A+zQVO0V-2T$RmHFLB1?O8W& zmHORn^&x|?w!9dP@!BEq(Gt^{hfYT;W>F_RXAXX~_^rwzV?I~Gap%=)Z)OO=j+fs} zCi;vTVubpfI>g=1nYD*RSI-qy<>^r29c_gh+JCyIaoK2-T!SAwCOWFWM(n3lnPU9H zLtr7^w?Sv+vr2u3<`$O z3}W;}U0InA`tG~{MJc8rr;5fAi)}VFqB#UswQm&*0q&jT=$HBixkfpm1WF8FQ|rdn3KAlNv@xCun7+tYaj}5z8yc@A{2Ui4f%I&35klg#@8V2Za*PH z6Iiw1=+4z{`@V$8hnaf1gg8p2fAg)cs9(m9bOwRE; zy=>gxXd3EvmMA+P;+)k6#;J)!=t|NOM4XyK8G=bDC4}JVB%+A)Yv-(ms3dIQeup_? zjcg`h1d(Kx_{h)taCWF~y*v@rDA8aBEZ)_xAAuj2P!Dar?+r)JMQ&GXAD1CO?%3$Z z7Lo~{0~dd}T?bHRhsr)#Vgq#lKesFD=SYT@@MjLlC*@vG#of->QRlDGiiSVJKx`Fv zlfi|G%`so;{6x9B=F;*p-V=D~&(E=otig&kh~i}Tu79{+&Wa3swKNqj>C3FNN{x+_ zP)$+mSuO&0yzh8gP(?}X*s(6FQ6OauTAI_V5P+4tdl^&>gwZYvWGn(Ol#W5U0XT&8 zNGUZ*z;lrGRJMh)S|x3yPHeen#27c?R^Kd(-8eT)Po)H)#At~Q;;ksci+Cf%$FxWN zxU3!J?9OAtv=L>!MfeEYi?sog-Zb(F|^l-~i#cLj9xGJn_6B|35aL;o85udjac)NYRZ6Wpfv zAI>%~2pZ7ep-X?p{QMQf^3VD|BbXGV|Ed2o;^nU}puem5bH)GY|BMFuxBSnbk$*0K z_K92nkNh90F#p#78KCf29Le8R@EKk5Kg<8`aFTzE|D?MA^Vs2`|118J;r?&=pZM~> z(C>d&1KfY*{|^xSzdQYj2mcFq{&&G5`~!aeZ(;Nw6H9;5!~d>NP~iW3{6B2t|6z&$ zyTzX_^nbSa!SUY~{~mPucZ)wS?SHm_`Gf%e=STSCDE?z!|96W&Ptm{b0e{z{>HqbP YpdbzY7xx?p_VYFL88PH&{@1(z1quXiBLDyZ literal 0 HcmV?d00001 diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/e1.xlsx b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/e1.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6647e2bf98867fc06b52ac2b3a17ee5f710c4eed GIT binary patch literal 31854 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�cp^6K^rqxkLL2sP~CbDSSYi8NyDN|Fm^$7@kd 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�?n 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 z z%T6HNWVkI;l`z;64m2-ZLV8~{L)dt*dIufc%|l8$_T4p3*uiRXiJ6t*;jFuch>mnfP7wF=sON86FgAPKs77cpqNWbn&y4*trz%E}86V zpAL;T9bVf~0uDT~$hC{CiKat7(3DY_dk4ti0-``L?&7kCXw6pXdB#)ne%T(cYIT zgYD_E@)>^WH0$PD{z46tUT2ig;(#^t&tz!#-;&u`{?t@4ohm!bA6mOV3pm_Gg6>X3 zlYKF)TJs;_)VB4#oUN$35`S?Ua$tI7y39Y3>_h7dfNrL~A6Q{Z70g1?OBLD`NrTb0 z)a~+yBQqi6w|vo2M)y&b?xrEK=P?^_)v7rzwUi&9zesUvOYtND|3|uf$>Lh0{y8sZN_UTwv-`uB5f$Im`B{tH zo|O5D}*F zzg3-gD`)KRGvmw4o(nj!uX?_{u%GS9MB5&+<6WIOBAZwC0yaM^0ehe34CY7sfy?5t zQ=3Ev-d^gigbwtXZaLl$N6Xt)xK5t2T&y#GKjKq#3I#>ET_X`C$`FnD29M-L}5+?XLqX}{YcbvIowVSedXBIzHwchy}O=NZOtpTn>i3qpx5Jw%7pH?gQ*pTnK~gaF!rMfd2Ifp zVD2?P$*o z&a#@ngp_PA&6G_QWjmE#O-KF`N00s1~bK2YnfRuMhp-5FUzm(vq%#cC%*YI@eahoI?T1Wx%jCFtOf^i35mcHa&ToC>Hq z5%RLM$%#R+a;!hwFJ-a>GdA`pbGe}jo6xoRHED7jzHwN9Z2!cFHoihU^Rt;~L{hag zz0Z%7=$+Ef$n{c9?VJJ`-U@tY+U0c*8@ZIaIZ8b9X!94*UP&RJ3v6AdLOjo**_z^a zYw}KM*X0t~xsGEDv>L=p4*k~1#{u`)x<}zl7#M|OBbHF zaJ=p)*CnS1TSBAuo}5ROToyNQ<|taFH!G#G@E$tbw~|#Xb9BGHa>F={vQSlX?;=+U z*JR8O$I!P`if4QKFW4NIwYgzR)*40(oCYJEen-oV+fxWxM~cYh_j3S%I^}N-pIMXE z-BpUGpM7MMujtS=B0@eoRSev))lE8>(eb$I3RBDNEnIXzMoQ}DU&0}??q?h4R>@Y# zHuVb?j#UUJYVkXAxv+4Foy(s|S8z;~cmp?P=s_s4#7L`QP5N9{T4y??Hxs>MKZ}$3 z{Qj`m3bU7QN-T?OgHE6FkV7j8Uz+lxgwZT0Mr3=oe$+wn|z zCV}yZ>8V}XX@Xm#^q#2>s2&G}zjINCmKsCTfe~=PwK9&*RFdZMgN1pVk5j#5s~^7* zaBbg1rM77iLefe{RS=Cf4?%Yu*@zoDRR$`uZ!{Nc?5)!|+9Mqj#h@{ie0YNkkCm~U zOi(8G+dZ=WW@fa{tnc?@4!k`ateNfKb7%S+^muA(b#1Lj(e@GPSrY6uJ)fdv0iY}Rizc+sreeae3JGH zMqoi_xRolzBA4W#8fNuCGq$I zE49s-b|RonCdtW=_FIggatKR+?!T3)w5B`)-wqcOx++(eDxX*SiJmu18GewD4iEn0 zgew#I$IiFVhLO&$sAVv9a<X8iS?~ajBb;*%3@Ex=h-$TLu-;z(Hk{PP@LTng9p`5eWZanBs;5O z`XbNcJNb%jjc$!*?4$^^#iac1Rr+IN^;nGGS-r^+qJ_i4=X z3@vj#=uQ$Bmj(+V(}2=VDvAbCP4dW9@=V7?kQnF#q~Em-aJkJWm`rs$Hi#uQ(Z$rN z=Vo?P8p55sE52g?$B=ByX-DtzD4b%rmF~Q=r=V+yRzp-uu9AZ znJwxWU)U~2b0!^E%nUG1Fs2XpTIuYx#0u9hS>H`Jitij4I3H+pC)xH^hn;@t`Pr4@ zuH}|YVr;zw|BzS&LccKs?bS>}b!nZ+lnTf4>|4#WhUj#1F+ZLcZ#`jPbtqV@gsOacJ|rUH-X)E$DrY3(ZPK4SP4l zy;2cxpOPk|b??duHQmE^l`%xp_g&_d-hf4sz*7x36RvzHq|xZO=giXC&G?Aqc$W1w zAZa?}t2*QgZ{8mW#tX<_U2hP`ddXh*q?YSqLob6}d9#NZ=H}>*;(M(vz_*sft;~_a zync>hJlQIOL0_7X8)4FHLfgU<#2nycvb1L=5qq=FEOTNe$c$km&hu!lRZv(WwKqL2 z$I;B9u>-ACWtNZYD^;bOh1C(~>hr;y`{-GuBlKL_s0v;v@I>jcW1p2hw2f^o%(RL_ z10q|vn7Xt%3p?JBn9W=#;1HymA821IcTx)iWS-XPUFDNr2{alQdSZ{ka}xJkLsk0q z?XD!*lYtlk`rIAms#0(4g^z?51jpJY-1d>6GhWIuzG)0uri&c3uV#z1@6l@TXtz_@ zxVLF*#9TW(FG^1r0x#7`4^KCb(XBMb=}A!w)g#iGxr0Gj)Tc{Ew_?1BZYe!qwp4qB zp3KWOT3SdpAdibx{_x=XnDw56r?Wh}67Syk((70=;i={IwA}AYR(B?yVl;H-)hp?h zDhnrXVYrVs&J2cc0+}}x(#{yPd#7X5?ze$Hj6=VJY}utIv1Qw#dkn#x_H9ci8XiQ= zbIZRx@U8SBN-C?gG;s`5T)26GK7(_W&3j{FT#ii%cH|neXgD%kmy35e$HZLA=}A%0 zlBywU@schYW(KB1V25kd%%h__w7{#wpKJJP>V{3PoDaPlU-{zVF8z}B0ivgg#HGXv zwMrI-$UTa(!iRF_rw@crw)nbb59S^zu!eR?U^YBWk=cj^vtfDaeW0A$)P|X1nuh6A z(RzxkcPnmD$F#{Zj%P&Mbi`*g&E>!Q{Jl{leH?}S(^Iuq3AzY@5Ck*d0nxB?03lOx zvnHZSvUb#=VXM(rwvjt=+cXBA9lxNQuR2=oGn^95G~;ggL4Yr&CB!yV>Bnc-vNHdd zy#0d}C%49JQv0_Ga&Mti!&ZEXin_LMKZ|A zq!Fwx+t#MNm-f5#f)~yL=K7`dz(D9n?!pf}9S0Nf&a88e(S>z730pc0at(xbjb;t+ zE;yqy{6!NnD#vb9r=>6KIa%T9=%@s!ZfoUyyV1k!k4X zT(^0#bk9Ocbb+*euA8`}SI2Srb@0NxHlLY^kwNT@^@PJNCj+gCTp-l$=28-42lS&0 z+Cyw7TJ?hw+5O4Bf>~LmNQOJo3klS84V#B$`E=U`Qn#NFiZEQ9?}m75zOw^^SSU#v zYnVcbJ8ThhO(Or0d`NoU`T722^YmQ@7oMSP=y~eHA>AJIbn;g9*Bi@?g);=poR<52 zY+H$L+ENzw41_wr2wR$VTpEM2j8&G+&f$a#&3xK1i|&B|HAB3>L*tN-0d4YGJ$o+@ z^JS{CqY38}(~HKYAbJPAH0ew-1KZ>~7)6JtimkBeo#lG-pCs@CFhc z{5?9qumJBQoE#jwb2KrnjgRDe3$OLZ_Pf7iojlM?RZdLpzRQt3XJBy0C8&W|2QTPLvSq%?0ed!saPPf$*`gx6H&dybp!tyP$L9D?h8rx-4>9$KW+%XesY;LpchWUd( zASURE-{8{!#1vc0=vi<`%e{n`Ro79t+Ll&hIkxfcTe5xnKKTb-gskmPt}qLPrU%A> zY?mgwIROgyrTk!5Q1*cI_+5qxn;c1dIPNnfX!mLJy!i%$ymV$nu)KB8Q8uDXO|IJq zQiHf?r#)6<;7O-!uFUg06)l<6=Nr~1Roh#tgM?MBd{yR!4aDNd0lCj9g!gr;w7|-gbyXTSsF8laTGLH3a2GCpOD8V zeLer|W4R;>p798|79>mSX0S)H3CQ@y3C)dz(ZQc!{UKbC=58VJ<1s+2KN#-cx8-uj zUeEv7vt5;o-DHlVlOhoupZj6a1?>9xIx0!Saw83~c6M=RRpSqv zLM~KMls9YGAoW=MB#FvJ;S6t_1{jA}Vdcyx`N2ma>O zTC&W)v?dkQ&8;)rH!x*?Z#N2~3ljMXL*-R1@dEyxm`|I)yBUkk_nk^KuSK4RfH6O` zbpp@B7(9=&z4u}O>gNX9*n9&ezD?=A^L)$W3;W~GZK>_jJ@+p2|LGH2qoW^+gZGqv1}b>z zCmGylIg(1I>qPp#aPw$4SEVpS$Fd649?loB_r|hHq%E5kjrTa^da+%W+27ZNb8@fU zM_>G+U9k}tNqmeqVKox^;Q`Q~=g|=yX|02oiD${PUC#x}3P99&f{Y)GMJTO5J8-m< z>UzbsENC?3Ci<2uWuoj_Si+TAQ&XLMafc^|yN;A=6{W`od{w7aB7M%km!*5+XvjOB zcg;_|ChQ4ELS{UP}wp=!KDFoh40Y_G2mGsj!)(1 zaz}C)H5b2^dBPXxlT~rhQo-^eia)LAkZs**0==k9jW4vik$6cBZULW`CuOKImOO^# zP5iG~B%1I_j|bb{ZV?uf(S%$PKEe>tE{f2fRllDpmO54 zLmRaH4#*jVHr*JaJvUz;KgX9AvT3DpWk%&$*7{E3fZ|nL z;~}NaZ@6(O???TWLg?1I%m!%zj5#f}nXYuH%Sl~27f)K}tuk%(8qTyj_M#whi2N~^ zo*Fi{$#a_buY7NHbN1j%&uYklo)VNf(RQ%k=+p;sqn0~xDIJ|K`Tq-ltFg(XX z+K^p9vqP)>nbecN$cl+N##6ib5w8(mCVE|mvhU!vw!K>aJ!Rp)Y7=(&SV3ZA^_^lh zY%m>ac(?fe!u)-yOc3d5WKy&Rc(rp1H#OsEqj%yuZ-Qu3-xc-pr(F;0+`+p+3Lo- z8%})~pM`*bbBt!6^1h?s%x)FzRGe$V7t5TDQ~}SKlTcjdGXeTovAo&ae;4`rdp}2` z7ZdT3pKf=7=W3Mr(Zu)X`mY=rL*_q$DZ5^0SW}lS=9xwrugdHcWB%LdG!o-n*AlT1!$ zU*Ju0fI+-PNn)qh+p^XJ$49~Q)G$z{^;QGRI4=d=E5v$nPBXqnM!vsIAWmhL$7Fut|uSDUu}8|u4^ zjpTPPhMsDmxJKZ`Qz`yhUQ>=)zxPRH`lp*&out{YaKLW5gTr;ABQEr?D~>qN`{emz^_{lM}`?`g}!+K)t5OB2{uJ)(Ns z%^z?t3O7UyGi~&$mha2D{_Yda#Hi#ezdGT^iR~>jN4(Yt*xi;TJ^yMOGxW?=o+psv zmdkgyuE>@L>=Q6Em&}`j0O7n*UYcX0*!XffGyh#{sRmKKN3Y|&HVd7z9b44pT`qEi z0mvTT;Pxc6k8WZ)!xN`C5jD2$_X%rf6>{Mw34=-%V@d{3mzTfUlm(7%xujk?#qQ&PUBh5iab_Or^W z7_-Oqcrt3kc)GQQ9_EFQkK1&e6RH-enl=rxSr_bA8EU)O3>Vrjd2S`RC)Zn=U*1X9 zWwwex(Ifj8=aDir&d0TCa@qOY^Zte>mpu&^PgZLhtB0w&+)bgASa3Y5=jBn^G*_AL zv3g3jr<1ew8vE+#gC!3K{|swOk0iPhAp(gmYe5WZ3zejPC{LPM>xT#QU$m{M`*D&$ zDo)RH=X#m>NZ#44A=_YVQ(VUDPT+KOP-_NU?j7mt9;+|2moGy!y3y|C(jVG|B8fud!uw z%eFVOP7%#B@ASIgWez=UoQYbDl`r2kAC>M|_P;0};i=Ld6S|(0C$;MF8}b7qr`;AT z3q7Y=-dbIM(z`ac{5q{~es_dm?v!hG>S8N@`Lt*7s$Pr3VsrLZQBbgF=2GUun)Qa* zbh%%yS|8o+H2o9v?%9DgBcCIq1oK{&J8M?7NDL(J%R{AT)F>JGj|ZL>hG;<{BIo>Y zFsci?j;igKv#Rdc_J;CnOlJ-SfqCMsPoB?PE58^olBYvFpkQaosR1*o6^gvmR=BHO z{MKSkU*7ci`hL10t=MT*JawE7H_GQ1bV6m$NunQe72PP5e+Vw+hDV}Azi9~M+ofcu z@<3lH^ezL{EL1!!0zF1~%BN{^L{ty+NZ*n|nazX8O}an12h%3o87I8j1BeDTO}Vjf~UttAxmRsF)HY!>OSia8r@yW9`yIM(4N!j z7O_2Z!JgITf}ySBc|dw{5|~m^S*FP|RFEP5I`gXwR4A|6p(1b`6Iu76;Y4>e_bRTi zr+$HYY}P+6X8tf-?KOHv<%QB!0jm!F zPMh)#DvrV?mli>F_-2G$Leq8hWL5A`T*&8aDd_J*T{UsuP+=!Z#r*>*(Z07L?%Brj zYl!3f4OBMOPE8Oe{16V`_c-8fPziyLJc1>{ZbvemohfxDZz+}>pL{Qh6X}80} z=&%goWk-tjR3JqVXb-ozv-?5|)Z5oW%P|2n6-D%&MM#7HH1WCx?f7@09oK*E7=~tt z?f+zk{#$T+hY_I~KbOOghzFyZPm2Bg!u1qsG$ZIV6;U?f!hZZ3NC_yp{c;_prqY|E z(yD2bhOaJ?LWD2d70M$2&{G+gc7MR1h$M{iKTmhC9xOYlSwFvwR(1rgjekU&8X89X zD{IFMPUp2(kq}Y(i&lJL=sEh%d-yqeO6(L?9NggNZA~+;F2#M1m(bF7&tuG}aKL`9 z`uwH^ib?(66CN4xI@;`0^Dk6mxP$x#4am4pSr^)oFze_1lkK&k1g-1Fh0|WYmZ`3( z8EBE{LfbS&3~4DK1^+_z1+@`yUkeRIPgFeg*7}B2_3p1TWo!4kvZO}iA9b;ikAZ0< zsK}<7i>0JrLW%+oMX7iN>+JmBcNGh}T3+>MhFvYdPF`O~rr4jBogFsS{Xq#PHO~SK zUqHFI?oZKcSS>!z4AIU-E!tjZ?joF2g$2-P|Gaew&Urq51<{DID)*)ViS|-y4ED(11{> zugv3iL;S@#NGu(@%3AxAxOok+Gu0P$kP$9y2fy0}H=aPRe-Bdm zsmlp_}@E5KygC;8jWhfS2TlZx$>R1@LSp8!- z#5$9bxZvpcoz33geWk`Y)RpYx$i6-3@4P$+oo~1M|VSAfQO6g zs>2ExpCq{9Xd<8s3}uQc&6&y)pINA0S^7}U+VKa*b`d`Gx@)3bguJcP#8-2xr+e}i zqP%yrKfpt-jOqq6llGM3Os}DkLQ=8%;#jjh)Nvns!sZly#-Kn=TU)0_xZUV9 z3@(zFBu zjTY5(Ahw@NXm9sy+f*)XgS>CL!qxN)Q>Yr7mr=^o|KJ+eeNA&9N_EmR5}lAKetS;kf^Z(l$$Lbv+L(!{KZ4M-zBI<}9?XuKnb}(YcJ$KD zbE;B{!48uhjcbBE$3}=R&W6s{NgMMOjUJz=7kZil&4E{Xm&;C?c}-dN#z7Ip zWzicyMb5U61e3up%0walX|(2 zqJgU(9;M4g`3$OJRWuBFdpUWHN;s zymw_Yfh?8n>sJ+@ka!3$4BcT+xSJs;9PbEoC)`p-Rlbd-#GH5n6P8R?*lc`2{c3m(MO{E2UhG8T8rBzSqF7 z?6q~%?Xaq4zGCG%skO=EqEVR+QHGPQ?UvS0Nb!CVl-qI$_7fSr*<1Jd@$Z` zosz%2BE8v2a|#%=aQ$8NUrO+@t;JIJl~bma5bKf3wtG!oLvn08kd_|BAx zj8@Qs3W!k^8Nt+QiB0K&uLO9v0)rNeT6Uunj3aKJ_ViA)FK8JQeg0AQ*>CC~B(>B2 zTpv^QBEoD;mm8!2>CNj%FPrOcF6c$d1cjGQph930OPE3e_D|% zj>NiUO?p+3sd(t?=!}$VOudt54}o%Nm+ai5{3hNXEQw`V)&SIn!mwoFqcmMkJ;%l` zl&`#8zAFa#UvDRR*QPDSX7Y6356Z*TMW#DVYC&G^^Pgx+W5Saq7Sw(TNEzfRcsfmF z+I?qruJqx!ER^x0>>KK1kqMDv<~vYex=&+kOVz7uvenJ=5`v@(mt);ZJlUZtXk@=B z%iuhnfBo@ak>InmyZWypy8&!cu*qU~f4%7X(jM8;f05M}Zq|Rn$sDyErk4XJfPusp zjU0$Cr~%7Q*We{EBzed(b}BxPFFrJuQMHhF3mk_~7yFTFb~dk{-M>?Y_9@ayufLT5 zLG*#49yHMG3@iwGQh6zf9Z0eee3OU zDn;vdqVu(amyB(kdjh=9$UfN@;<>S!#Cjpjz%?y6B*cX*I&^Ajr{afR*9;cB(FBz^ zRa#C;UfFuLUz=+~I&h64iP7tQk%8C7V$S41fIfUGTnkCwIx9UJ8OAQz{%F)}Wb5xh zdA8Z{k=i!d7a?AGGOjGNaXp{K9KIj4Hd%RdYRc)ij8Q0Hd-6B?D2 zK-Y&MKY-c{0~Q?bdb+^?Q%)vhhd`#QO$3ec1aTJO^XJd&4l*lH>wW7pa#g$s#W%=q zyWKB3f>`IWwNmx8rXG`rb);Wd&N-mV+-J=&l}Jvr7)R~*Vxw2pm@8a|JI#`GvW-4id^h%8Lgw~o;6YXe z3k_lF{tX@H3R!exqI}Inc6skY5$_ZMh_NIKb)S#w3(oc$II6O-IG&MRz1VIT z*1S(~^^}muRFq%B`T*ELgeaS$G#)~*O5qI(B8U^gvk#I!zB!#;G%lT;C_W_wZR-P+ z-TwZ*GqA9=_K~hcr%h7WqbS#=Pilmf_%Jjf+q9WA^Aw%bb%*ap zmen|qWKoy#h;sC3spmbUy;?6m(j9MmZ>G93HRCz5;nHBDXRtNf%tz4#j^Ry%|L@l1 zRd4cU^XjsEP-aemdTtdqul_wVj@GWEUBvTN9XK<8_L&&_A9?Mr;=f8H z-SXGL=vtH!M<#-S$6_l8;DCyY!NoIW`fOXD*$1QT>q9tRiO3+kYi02fo$KwjY^$2& zpZqAl-cXOM?Q)Rt|0R(flteh6yOVIKQhGA-xrTYq6%U-j90#VUM7 ze{X_!;U63t>N+*&tlv}wCf1L+ewwonMpz)7J_m}XBhFh#j_$jP9FZCOOqbEP`Re@j z^0)UXoxyi2>~?O!8nDMZZr`|Cb5wjsDAeQAs8kYC9yadByjJi zNa1RvCHZdR!pC(j9U~r8SXVkhdzc>&4exO%Xu|ZMNhkldCYX4fhS$VyOkSVSvMOp0 zm=+^t--&`6Gvz3;)-@Z+=PzCi{hY6xAD`G=Ft-OuA>+W51d{IiJHm_2oyKdCEgO9? z(a={v?mQv*5P^U0SciA0iff`DgojfFy*+wyepRk2Ps0NVD`cA5W8$>Vr# z_dat3yu#a6L@uKp7BE=A$nCS#!_ap*MSAHvS-~G4?RLvnq_H!-RRGD5osR8>mmXct zWVO`J4h@i6RdAZ>)P%+#EyINup{oHE=S4sQ4!A~~N7Ay2VO#4|9etFGTGgsy!gTKd za@vuZ>2e~X2$?-ZX#K&%BdH<|YY)axk}D?v;zoOVnh0j6$kHim~(m5QOtodC!Ib((4?Vx!ye^O*_y?QZn+&k-IX!M!g@ zzmTeq`kCFoxd5ODe??=)@3+E)i@wO{RYTTA!nM#B=<RW#u3~0V#L}*L8Qk;kk{02E*}LnDMWXqdpQ@b zRV{!B0t3oCXzvWL_vq0RSeru}A!&Q>bvZjl5fJnA*|xENVyE97w0vFkyqq_OQjkH_ z2EBxH@-0(g7{nLU&D>usC>h%?Lb!DZ_2@fP9o+vY2NtfDJ?M!>0PTE{VDK>3Ky9c@ z65*J?eaqLx8t>@?ve)_C7HdF+I@oBX5W3noOco&q62gUS|(&mO98{7$}vO7_Eup>E7r5gM*jsUN8IgxS27Bver2?RXkh1jEXSlUg5s3d1tprLjI)UobP zBF>DYAKo4l=g3iPVj61W*yTaIX!H2-K z)WctN(Z)M~6+Rsraz$+M8T~v~5}6`D>2S=b{m?639n@UF4jGEQEsy#Q-XIhN{>cGd zHO=|G%aV;R8M9DsAi&OdW2=(xxudTA+$4ZZWX3h2hZ!df(9~#>-!X;C$u(dnL((h@ zTGp#UpVD?0a}3Q?Ga{CCrvMb-0zl>Lf>PM{Ao?;y|1XICe+M3&MuKAnvEf|i$vE^R zWne>rG!?XiiaJ>J;ccf?1%8}k-|I*-6J*Wa+czl_vs5N0He+w`Ub>mmo%WP1b{*x; z0(+J`+x@jM1LH?;d_LL_1KLmLlGF&IS0jQ4U)${ALjUobisTn~>h$R(5{WaK#-0(8 z+@}KGMXqUk90)@11-!bl{BHUc=|*CUtZ{qW+f`|=;U^&-!aQDRg=CJ8I`&=p~zd;b1%|4tyw4)Q?QLV$9u;Ll|_DFbf!UwZgXi$sv)*T2{T zu7h&8asN4jbi2Uy|MCYtAA_NT`%D^Q0vAsDK4STrQcr8Qt!bzpBbyJ=?but}Js1rL zNb;!H!z&(3@E5QkQV`K5NaJ=#(2fqk-41+fr;dI`Qwv0!XD_0kJ<&N$G#B|U3zrfz zGf%%0*YK>vL|&yfLhn=A51LJUUct6;2VsWTJHn5g#lUn^h-SoAVC^=%RKNbiP@#1S2dG;j2ni8D!AW?d3}kcA=N(%k!W0x~dD_AwVo`kyxNJ|yC^=iw-R8{(buO^LF7ff_Alq`zKS zUdda1Q%`r#pMI)}2}DyapqzUP9L}fTrigN6w}9gkQ%8e(tnzx$1@U z=Uth&Pn{yJuDXsvKRr*T!Djd`Z(l4DwGrR(iLdfH*Knf0Tr}+E93Ttqmn7@&_c1*B zsDR{JC@d=CdVeD~m<}-dfcV}}{_B1`?il%zor;c*jvDVRf^sd}uY$e9@JU7x=|WTL zzmP{}-EE2hY&J<(1%Tp9-#)L~xmq*CG48wKa6Zk4^Qg0Yq?mQ2zr-j^Cr^Re@3p=f zy0R^g>?3jRt7#=r=#&Figw5W)tO9cTBp1{y`pQa|mk}-sZShpwvh+t@hExY~+y*m* zkB)8}0vP8|IH8PwK5(ihs>XexWnt`fC~p9akk)#&R;^=YBd`b!t|&lY1W=!=FL3R9 zZ(4OA0!pf_-lPSVF8$Pmso7^>Y*&|s!@cf&73gem;>k;9E~x!iC6_;|0tdi^bUfd6 zHF;1kejv)__*VK}& zkGtmAoikK3RPVL@@QUS4`9Sqk^>BR@@&rS{ktR4na!nO8^jm8r$Q-ooiWkA=~Ki0Rz0*-?xz?QmjK?>>Q z@Iwkm6`HPC^_3Yqbh{g}v>6gXVyrGrSr&N)Z;LoJ6Nr`cwy(F~HNdFtIK~qomFnX9 zc-f-cN#511jzxE)(`@ed>q`h2x4A(2$jB&QT1nrTYY|kkv^p`jv9+3=9J&Q{!GV-C zOs?YGlCy(BO@*2#MTdelBR4kzH3^bjT@KS!l@zAqmBL!_aQs6Yd5)+pt@(%mz0j<7 zy%O`lXlT$-H!~hyentmw-%%vDe8bHQN@i9bbP6;|i9$Pr7n2u?PE`{G3tTEoqdHMN;7?K*j?YS@-uR6a-tkF<*aW`$T!`Oi+N68{& z(xN1QbBE9^cc##T{E_}k;Ea?9auEive&5cwWbz3)ty3NPBdW9~a6zX%%aBW$5L_c{ zz3M;ayVBBrs3TWg1K>QEhbBM#BkpXe+j6K>shgWP=h%d`(?omygqvXr=p)PVG9Eg~ zLCO$5sF5#W4Rqq+3ndZ{%*-5RW*$tAvROJbta?+PI?7K1ngl`c1u0oc_D(VSxtIWr z?xgI)r8Aprw*i_{tdEtnwiZ~F+2QjT(;D@HS-s2d77g)tvQNYzMD_RV_tHX=*VbmQ z`NqQg`auM6&A5+<_wwaHOSjE{@L>*~^KY;hzH-gnZ{RKpnhHQgDGwCf+ z9}>mZTGAL*0Rla2KRy(LwpkLu17F`8TQGv1tRMdaPvkQh&Dy=%l@CRb54K8OY7WUL z&ayG&!sO=zC*q9<9OX-vrn(eWR9=3FdA~W{mKpUyT;s_;*2s;P)EbForr{4IPJyHS zB`U=nD>M^b?aqDn0qgaQI#0`9seG7YgF(~nBby1uDiZUP@8>#G;;JLeVtD{Hvu@j9 zmT`r?B_+SQzU*Njsm4kDrwm1uuxuZH)XP82(No%=RXk11$SNVaY3YkcxgPWO2G2xF zK(fBTvoG-?rw3P5*(Yo0ENHiG`@L$vJj*c*yPs;hbX9DOGkc4QbCwRKVOW7_Ti-E_ z-vEsgOI|ck?itgZn3I!ZvAp>pKU5ptp4t88!UU2^3oCIUY**mIa7liCn;XAjvEzi- z=DqLx_HTUk@%~C)M6Y9LXr1eqmMtov$M1WL@CY9`?b%XRYL%Wg`;coj^87|?p}pCR zWf^Gs^8WkbM&a2YUON72ep+44gO<20G_S`jtrxUBHdYtsJ!3rDbd7Y%p^ZZ?`TE-% zp9jC#4wSII*9c%Ta>t@UqIYT!+q{FgE%!dz$LB%YDx(+(x-nguH)`d(^1)r#YqROV zF?kLg%|9Ok1lmC!iwxBTl-^Vih+YZ%x5hQ&tp^M5zL&6?)=Q4Cob}EHEvA$L0AKm$ z{l?>+)*pIGdWhd*?vp1XAMY*LffBb2Kc~U4<}XIz`%M;y?*az$r|jCxnZ#%ESDed& zU(va_A?{A=?ubp%yQHljKHe|Mp+nEow>QsZjcpt&k39+Jel9>?sfb%_wOs9EKHtRu z%rC&fnT7WFia5tu+=Qs@1H&k3)iHyl`LMEA4$Z?qK#Zm+ct(Emvi7kCmU?vAS!%p| zZ8`_2Q)6BJ*LVF-mu1vLvm(K!80Vg$4bDFa7G<$x6Fm-QB&D;3auE6qi2inr9T_gl z)BwcWtX_PlIAK*&Z6?)}v#|U2=5mU3h^DIOrF{~ADy&|NxWhfK00VcWa!_Jm&Z8b8 zSJl%St5sm7M1A`hx3zAjTVndmz;5>I9CX+bKFV&hzA+n4_kmRBZO_zol zWJMA|8VI=m{X?Jig$uc+bVn`zRMG*JtG2d8d;|6BAa<m&bo`YYKw-I2@tsAbr2*oA)bkJ(j~gh3-t?@IF#*T5`}Ed z6YK}O+n9JKg6iE#?dj?1M7QZuovhN~$QY;j_oY)UVD1yKdnQ_M4)Kk(SV&coH*#6j zDjeAUV@T8aJR4DVQ- z^5-+1bNX|Dxup}u)y?BGhHNW`1OUPEzx^Xw47gJk9G-KN*CHWl{TU+_i^81m z!sQ;X)Tryi%+t}{esm6}?-`mtpKIVPlZQFXrPI%MlC@LlO-ByuZ9HlT^IgGR*$%g; zB4=(m@$buXdMN)Lr4K<=oMMc&4%uY=2rzmU$HEKOFAADJb+#OB!BU@$aT9orn&TVZ z8k<_bsUhv_tyQOhZmzjH$#*ZS*tK2zSPokpF<|j|OR4cl;f8T{{=_?e8~p$^)F`~d zA2DmK{GHVp4P?7?BfqOwFn>{E5xuh(;UBfRe()LY8KQN^L@o&Xem(;9P@Kl+o|Pg8 z7h&$>Zgwbeu{>^ZEl$eA6cS;A>SDy@?L7FvI$NQ6%O6*M3>jb)1_wb8$F5Xs`5|H_>MjLpXa;+odfVl{)p>avfkFd9HQb~=PGzO1&&eo4zDEML!)U`t z8jg^V5MMh#6^zXG4h{@^ ze3w#>_4qf@Kt6bgXvAO{6Q`d|3 z+#%BUC-mI@KwDqilxv8#4e0f<9;MLeRShg6nPuuBw%_p~`7=HH_1IxPaF=P`JtW7Gamp_V#9}BvC-(xq zKA%FlUT^_rBoQ)D64KCL1hM=|hA8fZwU>HF>HmUD(jOuKtyp&^sZ$^@q`}u^!{P=l zD-_IX-TiPc1e(1oW*e1~Jc^x?(=Uo*uh~W6z$9T9-fqZi`N0Z#?GK7M9LJiz(!_kQ z=`-qL9JQ355A-3!BlN+Wi`+LHqQYm!+|$uf9j530B5^BT_aOXo?jZ2X=c`F5ITF7M z@Rq&%DfEDUzcgTmAAfc^Gc$9E8c`~>H|O??+_R_VoUV42-FotLvmak!N5-1es-<<= zQde91POb#CEY8@cE=J77xO;J;WLlynQ~$!uvP^lFO7~ayV4Ima7k!HG0IRV*<2T;p zkAa>z5+zUJSaaFi<-}3mI+b+zTLek3`5u5=Xkfy$lluWUW(a`bu>c4M3{W}9bCyXS zWI&NDar26YqrRbG43k<@JhA-2j5I%=`E4E+A8iVU=rTyQd3~$>OM-aqHEr!k%&=0b z=$lpWYG)-ZXcZS7CBC`=r%u|(D)s=Zt3IYV6RA@qsoPJuD%=l-a<)H<@}`AML*<{B zwFJ69O9a(=rnE*-T7{blv=cFaeha{zo1Eytt6*8dKg&{vjv$0jj{a%3H@nE3tm5W9 zMP{`oW3XTTo@&Sup@PwFIuH^xA@LMX7iIV#KKDsM_uxbPVe%q;b~)r|mkT`}+?q3P z)lO~CTba5gMV**Z=toOlD}R20-0`heJOO1sW+py#y?weuA}I6l$Vo-`n=&!l0+J^N z`QRoxi%X%_)L&4jhQ&4TyxeiXvJYtUJ@*zS-|R2hoZcO@0479E@{3f39X?!;@C2?A zd33}UkK0sU*j_dXku4fqN{Zu$6ljmEyqIUkU)dPia`~dQ#{twBUOC#daL0V$5UboG z^>LFLhy`d8rc)XSl;LJFyN2xE(Z9VN`;79$OW^rRxO|r`*PuuXnHf+;v{~y~OD=GH zbARv?Zx=Gd=yndrz}_vv`Md-cxtEP5{=nL1E7v+TyUHpk$w+`^Z9kEvCsTwemN(?Ow`I@v}3^#0VH3AYhF$Qvs@1Kv4Z2G(NN9YDyKA`>_f>#l4ha6rpF0 z`Pe=G-XLl9LMq?w3U9K&(2rmDKb5J-k0In(bIhyf-;6d^AOiqsTr+=)JRj{hKY#@q zYQZ}n;33MYKXPOhlAMVr-$Kt@h+D96adBzr>PARV=wZ#T8(>)Jft}=VFMvI_2ay}l zqd^a6uD`{jK@WZ#+=Kl+lS9xW5-7sWsJT=N;b-`N5`Y?CDzO*+ z6Pf#Ogkfm-x&k>vA~P{W@RA_YXa8k8>m6!n09(ZYvSAJ-v4?ljbIviE#6Gk5-ULSt z&l&-K7j3_N4FN~|e4qzKL@A44$yFh-uVbpl(N`NO57{*S{vI*tuADP7o4ncA2f!G95DYIzv!k}{694Hx)!*CNZNzJ_^b@*Th`7T(|kuS**S-|7I z0f}z@EEM9ECOgD8H$Q-46cC}L<}dH;Jlg`EE4@M_P^if@dI{0@4rqy5S50PYr6q7( zzGg^U(86zO3LrmxTT-ktD6bd1Epkgm){!?J9h&H;*>i{zK5B3^WQGQBVz1zZ>wNeC z_9NAQLfJS1)RY|H*!jOuTKw`$qknS&{-3C>4{PgeVrW4D`=@AL$=?Mo-aWcNEW*V? zY;E3*l!frf12nG-LEFP z7V@mOOAUO2Ca`+iNwZ{Tx7dJAAMM3Vc{(H@_%D{cRo>E z$EjX_(rkdfaSX_r{G%0;GlN7B--8I{t=I^)u&qX{N#r27*305}L^rOY;yiG!&{)|R zCNnH12MmBiv5b%%WQQsl8mfd)++QIcKi)4<%*l0sM*|Aff#9D0aAu4OvwgoP;}#vQ zyM)LU&rO&_BG3s({~SN=uB)zo44l&hgD@;51Zo&yBKLt?*u}+}ng4Tfal(WzGpC5On|U0M*lUZm3Rl)0_B2|HhPeb z%A3;ZLH<&a1u9_&ImmmzJ;r(1<7MhuH9hSUFi$6-=y2Ay{^0;-x!DpSgs>QH;3V0$ z>gp>zJUp{^KTBv_$WXm8EY=>bjTm4w1m0UsKfh%X%Oe+{hAxx0 zw+c|mYMd4uHpq#puG|!6G#AovUxe0+b8G6y<2OG*P*!>9m}O@BdBZf=X7<|#~9nFIi{EGs&w8=gps zPf>tB?(jK5#Aah@Afh(to=%QfHs`BrJq|1e@^iKaFiw#pk8n~D8>kgbf^^1Y zsRcqyYpZap%p{#Q99$r zCVR!P}rZ34?0n^3gZm*=5;Ivi5^L8rmQrI0Sbd4h zd}KPi5W(T^Xd@~JbS>sKw&3zw<3wt&aJ)pIMBF|9tc|l9s9G7_oA=q=)4FmzuS7s!pdrIE$B>s z#*^sP&zRugW@UHmfY;(O@z?2eBg_t)V1%(fNM#x8pGa%H?OnhiMPkf`Oy(JoI-ee1 zji-h$K`i(o1u@vHl5k95=`n*T46E$*l7`%2aG9#_*fA@NLv^TCPm$wEby}9O(_QNW zl^g*JPKI}((o0B4=s^N$s3xrD6D3WPr_>@m>41cZg&6FakOZ8s`_LBqd4~@_dyYUo zr%6SF99rcK@*8zQdlD13eNJrDC*J*ezP`6FP4U{3F2rKCOjIy|;YsuNfH1geE8r|g zoV)eyst~h6SH5+WI}}8UZ^TTKNVk*N01glH*}40Qg>J+$a{+*YF2708IZ$2dsy*%2 zdkSK|)F}&?goLAyg(dyg-L7fgM}9-v6abmesqx!`mCNuQ^PJnF5#?JEP`*_(0}!f^ zFYyy1)EkPNJ)A4WoRTY0Q}pUGZ$NyumD28xG7q;S{P*Ko+$P`kW+~E1{lRC{f$1+y zVS&;J>C@nyfpd1Yh$nb_xY>XVBEl4@XW%n${84iC+8}StQp1^Cfz#o!sJ6WdR2V7p zr$&E%ccAhF;o7+eZ~c#6xElLl-4^bXs*@d%Mr{7gds2G(m0s8RA2C_BFxgeWZcrg& zuDB24>neH^kiA^9XW-k{bawOYbVeb#L6-)qwUDN1r+DoO+&a*u5MPEd${5A#$dirR zu5LvzShku?!2{7C>FXSiFrq)-o8p z-MLK187U7rXT?)z&jx52H*9N>KcEe$`+~9b#;iSZD})f2Z+VS)56o84qm~m@eT|@U zO!qPZCCwr(vLIFbu$~_+A+d}mSSg{wA55w@WG5mg^#Uz~^vY-X@_$G^h8voX^{X9e^PPk@Z@bgsVZgzKE zcFB6q@-hO5{KeMqk9Fl)Hm?+MG`+s`!gM$z`--frY({&dPJW(cU+AT35 zk^?hdyXBJs@?qZU;JW!WAh^`_GGczIyVneAH$*b(LqkLFI7(rFJ@8UKm=JF-6|!Nx za|}cZqefg#<{=ZGpX1XBSZVYmCGe>4OZ98lI7?j@573@#h1#x(wycn%q9XsVqZ3`H zcF~2RTHTQYSE?1hAr+0k2?um#+qzLGz&G#{d+D^abd(&mv@U+RQd3QOlY4ES)F9zu zuxbLvD^-Aq2P3=}{c|*|;%lL^g}xE_8N$fd?@zE}ojb^F3U$fpmN-SG$we(2Pi{ry z()etXU&uCr`>zF(^V?3?20?uo+#0WE9k1f&bt33S|F6b4Zz09{E?9HN@?W-E7hHeIwI$J3xA1FAp!T z^(spO>CK)M#I1zGU({a1xTuOKx-HHg@;_pt#wqPIr4QAuwa zNSf#R0fh=?A+tJP-?=Am^JT2LDjq!*Jz!RR!q?`eH1IxS>6j-_cr?D1{!A z`sODRq`e6|{?`l*d7I;0tDD+L+1i%b=}zhUuVIH1Zvs@KzO4EYdoLwD44vNL@Z3Sx zo6_#W>NBkL&6er@4Iim)N*5VLTlTzMl(<}Z21s>>qYkmN0Yl|^f6|n_h0gVIY0Mi7 z4J~SuY=OCSAo9t<06pYDu7xo^KdSBIzTjKPSwUW?RC>t}7V7hWrlUw9JNtA)PoSNy zzZuzy-dmw7H*V(@vm!LV9|B`^X=q;;{eRah(+E(uY0v;^z=_K z>PqxIC>JG7T-&uZ+R~wfQuIW<%e_;RG8s&t@e}m@n;)Yu? zE3r;wUKxDpz%)8ZPEZCaKN@h2g(ER1VTNo-dCA|`%OlJR>6w`!Utch#SWl;ioJLh@ zvrckN_2bi5|A(PJNf{FBH7%-}Z>5`I3N;UGDh7ympQeBod9ZXk6SD~`5xC%F6deOj zMuHQsVfs ze?)RYGKD4i9x$Zb7tBTfRO~D@47+>xZlupNio_(y?moMtwF`!9zP&|gLM!Qp1McjV zMTtzvx(5>pat(%pVO3WhnL@U!*0_ItT0gWT`^sBr8)Y_8tMFZ^#O=O>&iE>o+^mNy z0m~8|ESawlYt7K9VUP1NIuUFCYGkn^F`#;Bsyk}(AvFC3C2c$K4bsu`%vVsRz_)MT zDm?zf;ztl)0bk0t(E2B=YJLf1)^^MTGUyE=`d&Zi*#CVqH%}$IY&9MAOIUE;xLsol zmh+3vrh(Oo><>wLEjxYWs0#$xxpM5yg~*Thu6ul@z3|{r?ag^qpma&@*vH$J=b4q8)QIeAIbR8`z#(K|!-=GYJyUXc zN`uH6ueqQ&dj9i5R*CCn63{a>%60YctcJGs33fgMZfFhDk+%5%!;RQWEAbpbFf34v zF{oyyu7#~R5tNg^oo2Wa$fDvF{T6h8P?d}2ynZm9^utJ7BYv`;OBdPq7CHUlZ_Z;& zEVJEz-&*SV3-Kv@JTKX>-8XqLpVV^p`V)k~8REhqgX#lu<~)gqWjVZt;@ux?&hFf` z4>dPw>lPmSxSP$~5l^qs-?v@Ql@2lyGoygLGEw6fhyNjS3Pj2;ZP0VR+OR58$&#vA zh@s+&U^@pP=BF>__iy-t^=1%PW9%}-=p^ZH;+^ct&eob?1{S2&UbZtJgo949c^SZv zzMvRA7I2G)bVC^9lKHyx@O4_g^v841_m3MaD4 zZwKi7QFp1!Di^c%fcn-8P)D)C9X>entU4RZ_AExj!N$bbSc9cULSgoM_l&9r7JL4| zH7~M}Hna8=h_M$AD|_sxIv$^Gaa8b*GC?y_Qr`Guy1l6U1M(A}6!f}fD2PbyE{rzH zCac7p5_g(3_e=I6?dP~$xv|^>GpS!%Tm+-|LR|quRDR_E(ZbvUiZHM1KO8-upZ_>| zJ0R)KAhwT+i*ocAd368kD{84DbOJQ|54Z&y$@%K#pG}J}vn!DSKEhqK_=uJ6^Tb8X z8=RT89X_NVQ5P^*_~z)wm+FwyC|qqo^lhGPx_r3TV+#F#UPEK^c_!lr z30i98ioah9XJNrNDB}D-tsnk3Bhedwh&-#_CM|&k8Ssrd^7ld5?E~xS;Uw`|$2+;P zssr~uq^@Y&G{f|hgO;5Uo)yeaxU_y~DHSj_yy^Y;(ifAlcTna~LPP~%YMYOYK_xZ1! zqkR0hLDj3Cd&^vTm|o#O3HBOTNTMgeUc1G58KVS+(}9MDI%tR#xv|oeq*S_F_}&5ai`XqUA}1%8+rXp^z)F|dB}rM1wyY85MsvCb6k+xYf>A2?zK4Ew;`NC zw1?`rr?^UA`Lyg@eR)07rVP}Gi9~IyMyo=zrP*eI{9zdEngFN&mL0NCcj0{ z7QfQg(WzNTiLK7+r<8JAKVtS^S#>*NRfVP(|C1O1tA@<5=ifpyzMIu~_jf~s* zWXDfb;-V1JXd75h>(z;`tDl(<-}kO<^ge?2MM)+wd|dn1t%>9c=yV0sH}6gW-|@L_ zo}O2L`|l^Ttx(=Sq*v7a;|B{QQPuXg2xA=>EPA*)ApAjM@g!B0#kWatpyLn}EK2s! z6QDDNy!L+bE^yVB+K?YcR=0O6cyDn7xc8HPlAK@etWCAST=&|*SZ1ZFnVh5v7+*H_)d9|szU zWB!b$J1L(l~MXA?~&x*sggfb)B>eI9yAega%jk z?$UmqpuN-Of?J_%CyB|@e@4|j79rH|5yHGm7pRN&B8I#SEi9#z>SeNyr-SgKm<_|fc6 zMVsilGpS|r(jFff8gPJ#$>>Pq#Ro>k5GPWFJ7rO5AxX<8_|!VjDWiq|Z~-8}_X1(e zk5^sQmK=Ne4~KM%bN!(QP%ZO!XO^!=J~L@0#j)CePrJ1^(iD)5Z|0W&&f3~~b!5q3 zKS%A=b?6wWJ|TjpQiA9o^^eX);GKR-XoKNH>QXB=ob|I{gry=AOfj}86JPzpJ{d%* z9s?~?%z$tP>RMc7WA6Yu&xzJXwFmGg1xOg1eSi7Z%NaUpLe{0jHLSY)PJYYeO0L>ONoxnFh*qW4NC|9r@Mv^bhp6!9CwqK)^wN4mL{UE6_P+sSSJu?pW9=3L=x#^g%W|BB-X^sgxZ)RKx{r~U*CGnZNaXyT#m z@G;3U)@S(7NX+0YZPIn+njEOKcw`F!BnQGXi1kh?#~)b&WR~w}CzZTD``#Km%yStJ z2mz=S2uuPZ8flXq;+Z#?gOfkJ{SKU&q^3BNXITG0R)bGhSJzI^e;0Ba!yg}B_;NmYyS3WrkvQIo&{5ZwLBOve+`bRG91;Rk* z0iP#Bu@_XYziN996#{a({=a&f^-HX;8g1--oE5B#&wp3gF^dCea-(BOS39&!n^#hV1RRGZIYxt$Gg0c^{AZxZ;#aW1hOW$Edb-RJccVR^C(PL-Y&(wq zxAkTzf=}+aFtn6%(IfkihUIX?K7HoOB#Wr71gofLuz$wx^FLXU0VpOwAT?t@xbGtH za7V*`m2#=q`8=A+GUXbcx%I!u@km|?6Ki}R??`&;{e27aBxqp`9swK0k5nmh7-UG> z`sVH1760D;ejjT$XesBzl2z}$InRUe)-y6PlxF{t$MMC?u-YU*dLmc+cEhoy^h}w` zn*G(b+GQP?A_w*us?-;N?(BWy7iQdd9n7?mDG=~F|ju@+e}O=mxTW|jm5kMV6f?}m>n`#IWVvQOoGG0 zxmn%&1kXt(h@3A{|F!6G7+@pk8=FMxy4ame^q}`gi!;%I&uZ zCv+?DE_hB}z3-tJ4x$8j`1so9Bz?sXQLn%dZRDB9A*1a18=-W&#x!yt(?ud!!}48f z?VI{k9rV>2t@JHmA zBmaq^$fD1uo(UrmLCgaX$P2kecF;>21QHpcF+W3c&+-+fhh*ZVX#6Z5Sr8XU3ttVV z;g5x2N7D$we9lR_a;Il$UdH)6QzH`=to-#zkD=ak#nL%q2beqD~x%i7q1dfl5A*=I%hw9 zw!T49lfhqoI5mHVI7m1i40qpz`;eoUAV>c1-(Y(BNtkvZt#)-{GT!{9s=&t^`~8Z4 zMBwwnjt~4{sR^@ZUn{PVbR)%ZBLQD6 zhi8UM4zZ9|AUcUOlQ&Tk`aHlzMI6;}fd;?p2;&_eH~vIe$D2$U{zQ~$A8gHS(sZO) z>KN95WcrLSxHm6?7h#zDuLkb$UxQJnhG7&^2HD~GgJp6N0cqu{pJ+nZUcjgd8nSbr z7F`PCIl%Q-o^`AkYW0gAI#66dPUSlKeyS$gtrZ`!AslTi!qF~32YtkxLAu>Qh@*wR zeC0|j43A}pE(y`&t2g@rQ_hVzFQFY47RJUO9A3?}3=QGJWWGeS0k(|1IfML%emcKt zRZq1m=<3lTXOcO8z75vLbtn~cq9%we{~;Q`5?>F!U?HY_&Ya8vIf4QU5LM9%V(_W^dlV|xXqPBQuA@m34{h>4 zHNmy47<}D2$=Tqi;pF7YD}h=VEK^mtf_q2+H+W$;H?$#a2oO_EE)r?WDHFc19B8`C zn|AE#n-f9fm;cYDOjN^C!jYv={vh%S&>B5*Mk#+~I4MxEjkHOCX7a;Il-^s5{3jV* zW1f|8H%epGlO;du&(MhenX5;-wVyr}L~){Z%AYS{mGprY6^e-Vi|d#OOvZqrxOLjg z-hYg-;BQR&5X(3NFF^XG`{~{i6^xwH+xpT6gwOM5*?6rma8(HIgyAhF!taKt;E{{> z1Hx597LBO0{PGQ^1OZxR73&%Yaa9II1vrATYQNV(iF2Pbp&ttS&4r)EndhO97CF5w zLbHGaHwkEgI+C|dD{AAxakn}uj8>CnOjEOP%XsIdG3HX3LK+L|+L8~aM#@F85m%jS zvvdmS_{MF5QJ$yZHX$VlJ0#m!cG-}uqHY0R-m?d_*5W)zU6m-{y+N9;I^Yc>BHow> zNLr?1$~N)HvWwI zA^-C*Q^SmI27sON+INr($OE1fv9(WqoV|n|PD=txgO)uWwg0J`g8J@_KM!c5K9k9s z6jsghc8*CP>V|`4x_{4Yu3yz9n#qjrEfiR16!kiNG}exdwDs|Y6hl*mv)wuTi>08t z04Xn#CqxYh#3*VK34pq%KyS-l824AAek-X|;kTeLSLeVtGJsiFuL+ zZ1n2anwOv7ZGZ|`m{tDFDoP?}M)X8^Pqa77uXh*$i*$#@iU%L-@?Q2Z0CBKuWb1U{ z8?>*N@zev-vvY#U--)SDE~=~FIEE!e_w@Ct=(?4y54-6v$td=J+#iAR>52=1SWZr4 zV?Rm0{)3NG#Gx_R*RM{QU7Um^hAd)Q%z)!y?-ROOm<2q@ud6e=($k})1zA2Qa=9??WT7!1#K%dUQ(2n;>pcQIB<}}*7K8{}D9iF9ew&l(n z0n`(UUv;@ci!YGan@St5H&XaxhjmzzRqKyl#XpuD^Gg;^nT{A>336BLc??3SystC%M#xIGQNvq8G_n8f=Z9Dz7BF;YYLyt+ zD9|MsCgp#Sq761m+nqraDTmu)PbfzF&iLP)z8r>@&rQE(fs_4mITwp`$T7`w;@xUd9K-#5;(1%J#}CxjRDMB0E-5Cn{`=WM==)>OW1?UxBwQ2{0vI!K z)&=Q_vc;6+hqpQ|2rIh9Ec<3UAc?1*JPT*J9S7yKdTuA<5DOJSyiKyU0Ud;~S->g+ zi;$ynO_^r-u{NO%h;bz8EJ$zaE?bS^GWkl9x!GJi6#iG@4h1JyvJ@>q74_+93f~T zdk!#lEX!*b=JDPMK5xfCHPuGyI04gSbJa zZm0=R3&Jb$)c3$s?}fgLBlaSer{RQ3w8|iv1&vEpIU&qw6=x@5{l` z|3hi8AOX!@&fU*fikUt0ZkUUzN{ky{NpTE23~FccPjl{BM0g33)hH>s;Hl$PuTLOO zWeS|$X+jtgBXqap{L+}EvU2E_WO>hCfh#uqQ-1-DE$)VF{EX+ zApJ9*JfDBVQ-*19ggyEX%VmNW_NefIZ^sqD3d%Ro_!@q=wFol%acJdh0%R$|yiRu4 z+<-kw{o<6{iEJX4qZwLSqO%rbv&g=!|Iil%7H!X7EpT^Y6SYYRhiQJ*wJaQFZX!Zm z2x{a(9PZ&2gpl%9>QeP*qQebO89(kvpSDJY6pz za5w8Eb$4sAoQBVEMgV~?EWegwUwG43vkNm0vuFd(hEFxtjMwpOaXHk*Zw!xe=wK09Ll;0R9TQi-#)91E zl7{hHh>lc%#WubXq3omjq(nS-KM`NU5yK7J96IYnpA-oon?tEMEo6xd5q)fPGQzo&KZGqsf5-T5&taWt5dZ#l8>1 z++Zi5MCTp9Zel}qf|^}?F)br)P5&B&$$j}o>tTg!F6W4@oj>Oy|I7_@?Jm`gU;-*? zB0_5NJIdtO1Lt2It;Oj`i{12C1l}!7H!7H#;rd}(G5dNeFKbC+OF#F@ki+e!=<>$? z7d$$W_dY{6mnqkNQ;%$z;*ncWKFE7BK`1@5-|a)U!BAhjL=6CsmV|2GXmPV|2&<@V z{TzlO&WUtEd|M^`qMw3A=n;kjmjZ|tf0KUoLI``5(u!{1f=0luP8D>g(aHZ--l@P4 zSN4j%JWmZ*uJVuFMeGS;x~MgYICTGFimPVnJ1;|jDXlUAY8Qr6i z781I{%U57f%$9ur6EO?{5L5@~@%(J7PU>#YI&_~Gk>2f$?x@=;aQ5T#0~lUic5mSO zsU;`hFDtc6eu92m)nlehAM1A7oo$#yps&qwxjpGcmuS@`nBvj}-Bfgyu3mK*b-ujU@SUbghm{OLs z8L=U1eZC^HjO^xcKt8UDlYZvm5>bSYxASaB6EPhnbZvzCZP@!XHQ0OWcTdY-s6cC$ zTa!QNP|_6K_bls7aSBP$2|&ENPkriLRKPfjA zG56b}e$SNV%n+~%B&*nE0#@JzH`k%HO)fBZK4!`^s=E}5AH~H4uf-zu-{6!xf(@Qv}RYh*?LC)$A!@~vViYKuFP$cPJC5kZsLaq zEpBepA7oCOHB{bR7X9(4gD~Qx}IR8BJXjSkC8l?|>BcsyEFgDZbvh(!!iNy4@_6qhC9#n|+Go07jRn zA1xgn)L+b}^mtwFw6a}J3)A@qtjsgaYextD#5)&uo}P?t_I_U%lq#(sT$Y*OFBRqA>x4<4bpfj$4M04XymV!a#tkrR07v ztW%~~F}ZN?>!fS~(jLk!hCQE(AWwGxH`xrd8viyrSMKwDYzd=n*y31QZNvzZ#>`I9 zZLMo}7l)lCSKw9Yb0G#93&cne5yrL}(iZSyVH1eM(ufJYFKSLS?%Uqvw}L6%DLdcp z+C(>p5pVrA-j_m24>^3e>HSsJ?2;wR48z#Af+Q3rcQbknKa=j8D=YGI9E6DgPtRU)WE!A}j@?^2I$U!7hln-{ zI$O$SEUZ**V^~qbo#kYH({clh-;0lW_05x|5BbU~DR&>H?wM2_?#_Mif2vqo;Wn4$ zSbRw*pTljgpdts7dAW#q%_wVlYr7{H_|4*&k37A{_D18Aw;&a%mgGiM6q=T3(j{BLgGrs6GQp$kuO9j<~L>j zIsDCh$Vw90lqvXWAM}-rQMJ2cxpps1T6$4XN*$dOZvO|-WnD1DG;ss>M9|k_5Y(5* zV-3GqodKE7QG*@c^Ee+1s=Y><^belH3WVL3^10}4c_IENT4R$6NJx4miaDE=cil2M z4hYagNk|iXxcb|%omxnEYp$oGE*jH`OL-R*J6_!L-K*namlgBg&-s;RcE^>v zO;Tr1IZ5c;Si-;zpK0m4`YhU)!zX}g$qSbg)wh)|{4_-I6Eb0W;9bGWp%2hIzK`ZM zhZW)myoH^N$2>0#_9+kH4z@|mmLIu7_xC$ik18!#18O`*>(Td`_6{qHv)$afD{2=U zXU={1Y}TZk50>4x*qp9G%-w)LJf7k5Du44OVfFChp)BR+UC&eZCoWzt|NWG~rh306 zU|(@FWU11NvzfiP#JQ%Qxz6np=RGk_2agDMS!S8S@Roxn&kOfTAjB?(4i?r{IN#Sa zxL<98^-@g+l1#6dta^pQsI9D;27T@Cil^9j*yjn}9@aUa@2freNy)9~{UHThiDOvB zQ(*0Q(GhGcF%w-ZnzGmou0M)r`QSdF1Wum6kGZmvBFpLE*UNPHr96Qpiu&Q<3iFY$ zBcRnYcV+hsceetLwy2`DePEDqGUGka{_4UzP{0-p{i7aT6JAM_ZRX=NWdBB){sR5% z#x!U7_EINGnPS4LCzGkSGqYheP2HD;{D{#{29io84cfjx$)`f8<6sz79b9qr_LGpd>Ee!1+jWCB0=PH#G$@ zYU}OJ{vtjX4Vf-^FFs67B61i%9-S~9&CfLD4y&|bMmd!A>fw!g{cdlOHsO=;pP!E_ zGjBJXELqmcccM;DLvxLIO(h%tuy1|A!~W9S51WNnkYDEBrNL&xQE?e6+5Z0YWFYhK zlL$(Gg`nMMbS>rLK6SsM)GGfyhUjL4k~_+O7$|2uqZ1;cH(O{}v$us);90AubjO=;8<)GR*L4Qn?c#awwM-EaEE^F*>0^c_&5!A-rBw5 zUXa}&QS7+5OUr#Vqp9>aP@p1|Opo+ zmA{`}d_zf)^fMzG5t0w@kv5Nmg9v4$~kEl>zUu5J!$psFaf=@wyn0~$`<5%%_sSUvCPJYtUANgjDF~9 zw6DC+s%{+HG1}+*(7)NRTDAGR{l(jsb^oOR1x>CFhR{t-TXVjXrD!nWEd zSk5)lEFF#49uafBe&5kr@OkKL-g)`$NmcXRE=?AmQH^FguF>ZTbUb=bA|107%jFw5 znt66k<^E>2%JDp6!X7wPtV9e+o-4XhEotWyaoqAkcI7LMMlz>yyd?6lvY>+JDz3+;l+?dc}HAM(6e%Ps|R%1R=nh9vSmXyBP6c$pKmn9KVX|cnt#REW{o!Q_ zzWQ>J`Aws>s$DeQR!{Crx4BRu?GfI0vVWb}hXmNHj)M6CAp*(?QohQ?E7#MQDc3%; zw$UktDV}cZ+6ME}QgT&r$gu!)$>SSz+?=W~*Peg=p?FZcnm@HBN_lY`!%~iBXbL8xco$k-wZ^~rDN=c1 zT2AeBg}t#^zpe9ONV&M){$hw#V`?$4mfEr+3nv+6lZ@~H(^0Cd(QVLXeKO6s!EuT^ zF0?S1>}coWH%g1#-`K3m;}V>^?CVs&b3MKyHBNo)$H6Ml8hgIQ5_Yxv>! zd0|otqp+_Vl}}gs^~A&cCq1xaWE^EFvQg&_Lde+0T}WN--XA^~5{RJ^jfl~b`jh4s zuKO_~$Hi2kdc2cZxHHvRD}0-UyF+weeeoxkUU}HntTq1GbJ0Z~dQ}@5eQRgmifxb! zjlNT4+{k#1I-uWranR{V5f;6bO|k0Ps*`f*Uh%k}4WXlD{j?6@6#G7fRow5TNw}Aj zC!?tS$E7zS#YPi|)W&N)gH)e77n?^Ut@1m)rn57-lHy{_g^TOkI-IljA#^@mTsjnB zV2>`KD62zl{GLwk(<Pbni7)C~%yu&aJk-&18v?Ss?%eF7+OM=54K}in2ys$e`a7(3L_IAcRB9DFHgtA)I#I&s)hZO zBrylfrBgSY=GNQ1XZnh-gK;dpg}!mZPi?ow&8th9i_}e!iHO3ZqGi^!xTJfTf3duS znVD90?(!S`l7P|6xsidPUh!z`DlwgNToI?yEoQ8Lq)#intL03K&j7@ABLkUHRZ`7(}PiJ(#n)74}* ziFID_m)5&OUl)0IxbLgy1tz``S|%pG;n~Fg*B_K^M#Y>veRRhU1Da;3k-D+H0K$fKkVGpyc<)jN?*tpzd^tnl9r^YSC z*}J3tmDN``_X7ZfvB^_uVkb}-Q~=Sg+p+2$r*kO;%FSh;AQQESDdT)0Dn7MI*0-SN z_K!dFbT#o!qsX(BAIdO87^Q4W(jb8IQJ1J3d9QfT|L5CV|~7RBNan<1!nLz_j$Po11PP_mT_;;xYE&E2m^ z;$GYLJXvPIxA&vTYL)X^sgiop_w|%=^?ZryW=Q3>=3BS3M=+e>;U=q!iK@$%j~F)V z+M%@T;vt}JOQ~fd6w|jrco5}JSB;TvmR|9fs$a461H?%*EbF78CA!2)+Pt;=VHh)}j|8L5~T(Hi61E;YFghuFgTmwEO+@#-lz*S+woe=F8#Tw>Ot|FPa#cIO zhJo+qWb{RnJ-V?*abc$$(;P8WV&_X4D8XTGZWo)ost{2zn4AfdOvOrG1GhT5vY5-M zGNku5?rE4hN_pXQ%LB)OiWF3{^hUltwatpG3|oxWlLHjsFgo=S@r zeVTH*1z@NjZB$A|W%qPxeuZEZrEK_8rRsrgr=#ZGf-7Ea$tY9bRd~ap_h|sKv)w=+ zN&tRK+=vT3!3*@)3D)#!`->LL9*;Vb!~~NcwDJt#29U<%7l+S2-*f4=Rhw;bv21!R zu95$9J)uR)2F6TmD=c5&%x9;fd_DlhOkbERXb3VZA8sa%?c0=39NB`G_NnnCDFuC) zZW&H^6X^}8u6W5A{dvp&R3$cilf__$a|%5jAK;4 z#b?BqD60<|e{z`<^XeHyZuNg2`_Np;$s|g%^kFTvC4tkaA>@bZ@U(DB0cfk&A4WVU z5BHXq-YkIAo{?OfVVD1j;hzjTYL8CQz6b%(c+0Fuic{It4?zcP69%0g7<;#2{yiq50O>NuJBuRw?S^VmEC zKXJ9yq#$q=%0$k8FZ)vluH@odMaH~Q5{s;N`kH%x;Xr4A1HI>FY(>usT{FwHoIQm- zqUQFttaJNR#jx(lfsw69I2M(rIv2YPGfO*|zEWc|JY6vkpSk?3ELmT^j3ypOQ#G09 zQAC95-dpXzLC2-19d_Z5m368CjjUdODDi&6jY$4Smsb)KvZ9E`(BB(dRVe1qEj)8v zsWQ00#hHWCIwjo6Xng)EX9G^47tKA{5>0l(@<}R!@ynG88#1wGB=kgu{@NyIl}QL8 z?*v6S4Zqiqa~e?58*uPCSQxD9?<0 z_F&0x$wwqpii!%G+UKv(zW}~+<{c(E-=<-RXlrE$SY21acJRO5Z zElcV^5!6w5?yknyzh-2=SKq5=Y|U&o4*{!TJYnqaj-XOmhqYy$(MH#x4VunbG_%87 zf)2~pBCUIheR6lDPW<}DN{Yy+`4kQY2>)ayX)l#|URb zTcZ)(n?0WM)PP3}r3@YO@6yDEF_5jgs0`Pfjcy7TzUcrJtxi`IB86>wW{ac!9BA%` zG1w^3Cq?}kbW-d2n(+QV!Qw)Mi`K9v1?~ggQL}zT@VHI*PmnY>O90v0{{yn=At0M> zQQ9UY-t`&XF#NQ7kL zhTnrsap!!M%i6V;8)?(V`x4MJVm`0mm@qVhv~vlHJ9a68$?9z%GHHh~W|(Q^4)e(5 zqpSNi;g0$Zl+jt_J}Vcu2^tu$bXiRJQbA$M1zAN0M=_ zF|*UsL8qL*nQTSo(x^|%scZ`RS$BrR6j7(dkgYLcfv;mN3M|~Cd(A#WW)33}L*q3I z&3v^EJ`wHXPoL8bMXt+8H=}=3;gSp_L~EWd(Qbq)b~J5SZDj4QI9iF$-%;yvQv10` zx8N^R)9yn0$Irf2ueqy29ZZnaUY}}1WvVw%B05>;?WVl`~Y1lh(|4ZOF!}=A7$C} zjc%!QD8l|L5Qfoh-CEIdq~?8<1D<;t7Z^}!3)dLoQ)u=` zif@a5u?7oBm?0R0y8wvPLq4CgZ^AGXlxtpNiq*#3_#~)k*OkF6e?w*$%{WPWE?Cb~ z63Fn~BYMv*hsk>?x|@G2tgm6H+XnzE{yx+{Hfc8OFf0@tC1KvzUhw^)YBLUa0O01HBT{jk?)YS$JQd-aGM<7@mSNjL&Es863jyG89?*BYTxI;2!JunFr9U%{y#fwIpjNySo zT?VD|s(7#!U5aE9m>`pI`_XXrwKRVKsps@{q}kwzx#0Iztr9ZqA)tgC{X+wZ7a&5- z_nw2Ub%YNHa7_KzDPSAq-$(-e2R_U;3hvFrdj+{xR4~0sL8zMY4RTLTQ7Kcx-f1Gg zQJRdg4dO%~55&`xgnjI{hjFWjG>Jfvl4!Wa=EEOxE344zul}`x&=;{c15e;f1%A{7 zVZIWneT%QbBq~B+{0Jcz5YD|PY-YV(BYH+k@WKy;hRT);*Wur6Adz_a!=n6#5#3vE z!>DawE_nGpMgW7?k72b4)ncj< zDndi!KD&LDWm8xwP#SW#A41XpO#X+Ccjmu0K+>AwVmt3&IF=R!x9-BlFwS0Bf9{p+ z9tz~Nl;O10Ox&5|p^1}l(NZs?R7P{~$`q|op%4rWFT#hdFZZjT@Wr94&dZ>mkoAjLFcaoqU`y`wil6O>*1uO<)@u6Me*1SzZa z`Ma`LYauDB0jYxfl2C?+&lh*d9_^%^IW0v5^yzkB^ff=CNs^mn@ zMh!mHrmvQ^mPTRrNrn}o`rr%MiQyg#{I7f5Uoc~MH#x2#f+~-;Jwce=Z|drpG6H6I zA%uuh2)3g=34E6yGk@DW8mFyK0Crw~)Ny5GvLKQ`j~(6ZtH>d}@{@(%yiN+w#(<^j z?@lYqO1c($)U74Yyfk)F?nDy)gx(iG3F*g1$)$OKG}nG`S`sJE;^$D14Yfvgn(SftMo2c)x+b@IJTRP5L^7n$!MC z4(en~ygS3qUK~_*Q^&H!P!)|qCi+9a>BDx>8Mh)IQ_0^!lzm<|jQ58arb1*ZfV;eF z8svQ=umJHxpNGHEm}D?> zv$t;g&AbI2l=4854y%n$NI0s$Gz_mad}9mAKov;ZfBivbxys8_;0}Y-b3-Y)&iEaH z2dx^+?C&WF45DryNb#pH0kk&wFI(lx`j>JbJ9Q)J*nuB&zY6XzweC|TU zSRGY=qylJ7Ke%_jMd?hSO+54bMSC+>A&K!Km&ORubN&cnLZ^Cn>a4;$f6|S=TH@9< z&=RL~yPC0p?J%ROpP%Kv1)At+B?a!-OoT{>lC%F>Qa8+Qdg@R9oT50k6Dp8jr))QJ z*^EUK7a*`3!fHx}(n&kWp~~$=Qz>~vMQ9hmGf4QS9RR4j+cRC+ zc1H(W8b`}yM=?<2yfF($f&mZHWM9>FozDWgBNs4fEnxqAPS4&a^kxBn zbvt-V){NMs%@_Xb?kFtU+4gK+#ro<6iU}qw3yTg((U>oLlYb)8D~$blIP zn-tMOe1%O>FbCr~Xb7>lgS$r5VDaDGQn{MP4KMo_0c!>>hKT>?DyD06Zwupk1@X30 z(;sZ*YQGZ6Nsil(d@;-Fs%aQlFwwZ=Wmt>~l4)&h>MU)BwTqUoOOBodl_SG)l?eGq z!$E~X(C%DT}b2W|CKPLr z+<$l=cQ_oBA#XZkHYI>LRk60@SQl6mvsn6ZYd9;({`y7X;;T(7U zb2$0ix8dZEXA1U)t_gMh%Pdvty%Gsg5%TOrF1UI%iE}Q&;Ot!uDq+B$0>{2cv-mP} zf=5YH!8XdN1+)ENhht{CCV3i5LAWcrX!v1!c71s=ST=)*L3SbBuIpQEFXBNF?q0lY zBE0qKKU{#}?z_upQ`G6+2FZ7F;HBWleUO5u=EtgJs~`r@KM66wy1iwc{{t{P$FTR1 zjdnjMtpixqcq2d0EKUxlfdcD6p4)Ew%E6O*?vp`!$QN6{N0IVvzh6AXE?Rx)jSrOw zTX~@=UtgL1My^*Js8UWOdCT-To%NW@>5V@Hy8F7++vGe-ycV zSHfl)oa50`f^lPTI7dh#z}f7j$SL-??6ZUa`jn?>pmqU6xi#70_67?TSFQy{cJYV6_btA9OZ|7X^wW=4X>Uj7cNREa7(k6^^z%RK5 zoRpPjYstq#+OOWF!*nn>kH7|7koQ7TU>7H_c-WD@fhR$Hl$(RZac}A%pqcI0B%4J* z0Jxx9UW5pvr}r6~Lr+x`ZctBfcW!I-eXQ>D)`zCH#1Ki-LL?m!xyA&io7?BDf|t~H z5If%5ICU?;0wk3r)9p6uI384Qkeq5n79sQwQlGRZ|5xfW!slhmhr5cm*$WbTI!PAr z+hPU&%Q+Fl3+9kL{90m%C?C*-`EbFkREuy6;K)}{u0BNd;wzh)ksP2HAepnK zRu);_{rXGzeaDyr$~$XhctBqPewPcS+!>Wn=(@@02GHJGCRCz&dYX{&Ko z2@tpH_Syf0=CzYyMeRdW6z1siz}^UTfVHcCDkzu|oq1_V6iq~(KGZzg{9Xsu@+3qKm$wlhDU zfTcu?Q7G)uMt+r$w)EUPeY^mr@qql?d|T=tWeEB*;cHDGW`-y%B|%WS0ZnQG*e0_l4BdKdQq>6RiL}Oi;f)#YTqWur9l4S zoWA0$`|$IA#C=eDSUw~m?Y}h=elZz|`fr=S7UIVFdc!kc7GKhK_@tE08`+H9M37c1 zDsm-y_Jolnc2Fu3WqsX$(5Ede>%LV1zh8}6_IHr$eD!FY|AQuKp2L9OA5!8LVGQv4 ztMC3-7Qh*|Ls*Wg%$_W!_kTaJ116-ZhS%!z?r0!Xxo(K|XXPG_j3KoQcaIKW-rl9! zjRdQ%^_lLrVQWWrOjCAtqFy5W2RACvsi` zghO|wzNm_qziKMQ;nBfcV91rzcb!@LlMO6pVd?E(k7rg>_c>}O+nt&2`R^xf56u;Q z*VB~Td7;xqxj8IiEX-35qucKMlf!O)w7dSZMW#I8v=0U@&?COcKTZ7`UEqtvm0zaU zJC42fSCw$;m-jwv7Fk4kB6T5Qe7<@A*nK(gUH?5|j^1BO!2;xOK7fMU$m5H+bwEG+ z*Uw^kUkK%1e2*Hq;UbyR6V7r8LGi^U-sa@G;`y~QVB-x!*=YAS{)%sUN`ptQzN;C3 zPmH@V;@VyMpef8@Bh&XPZtResgqP8;N6QW>rR_ci5fA9^d*r9ALr5*jxV7j(Cf!vK zanQ#JCY=wK|FNupZ53I5#T6qxKdgVWj}ddfUJfk&>Y`okSsCDx%!HEA0B7Q;D42=- zO&Kh@tPK{uuxls%@AWT17XA3Yi~g|`x>G{pzblfej4#=Mz9mVBOS<0r`Hatv=bz_G z+5|Q5an69Mc_PGp73qEg(Mw0aPTCy%jD)c*?c;0<=^l+2vXcQcMn;GY$P3LZ?$a$Jr3zyV&(Q7K(XR+=o zqw9}rc8B{rbFMs07R$M^2RuG6hM;Fd-ufT}Z|$!{a`Q+2Uoruk%2c<%OqHH>sUV8V zdcL=kE9yebt;h9rRhTpa5aQm8B|_Swb2+_#g&5#Vlyb7fKpqy+rv|R3g|!%D&8O(2 z&8q=r=msuj7pRGp!~H4QTo^KHZ7wLW{VRW91zo=M+RuFuYSp{3C(p;g+_0B^vSuH) zM}0oD)Z9$G%(G`ERlX2Jsi77<=C|bv!uhgnXb{Sx9)o8h20pTx5!jZlmkOWnvHV!V zdnRhuCX9AcxRl@VSd2F5q2)9RdjcZnTSZ?!DfQ;Pq5&m?*CmvoOOoPi8Ng|;xz^Oz z+l*fK0bTOGc(wCNwD+w+r~&v;?Kk#t*u`$VG1Tz6m37wl!?yaYDXA%mnXek&U6Lcv z4_*=2pz|w^&}9qv zv)WP?=jfJI6EqU#^VA%+kNQY8eTR^q4FZCK>m=;Dd1glc0<^A(C!3t4FNy(Y=Xh9t zcqHZYRHN^Ji`DgmI4FBrteZ-~bF1adSHjXckEUB>)uE(A@Ts0^YXCVPoAj(!w8~w- zy&*ejMKUuPd_I;_Eg{C=1yHBg4?Dg_RX`0^Tt4zF+U5!^d&Uf+0 zcNY!9SUr<~dz+Qzmz;3twn{e@S>8tU_QH)sFsWNpiMFKd(DzZW9h#p=M)qs}Yi%0n z06J+7wC=ZoAj}zX*Yb0ygVzayAEu!zQrFkq*Ri91^TjjJ;6%gNvDVGI^?9mP&qUE{ zFPkbL(=&BG@pKq+S@QP))m`27%KYG-HynRSOL@~fWsoUn?>{0bT7R7E0em8*0dM}- z_?)*L0Lv=I^rU&%K$q|4|6hAw9#8f5{mtp5gA!#Zg+pc;>Y^e#m05<&Q)qTb8Vph5 zG^Zj{gTm={%u|_?GF&C4TV#wxk*=`_#SxyhKj$3x=-%)1{9do;^}L>czW0yr$2p&~ z_u6Z(z4qE`z1P~8*0&$F=uZOcicNCmk>vK#VwsZb12hJ8^~h_0$J+JD?|oKXz=9uN zmR#VkD+!q}b$Yl?|&q(6QT)dH=ZJ&05AxQ5~Sg zUBO}{6|j7jTsE4?ftv%+cFY0oDh0E?{|FM_N4ie--awRRvjuYE)n0*6b?cT zZiY;+N3}9={0rUVJqJ3i@OPwf3rfQpAUd1}5@tR4%|?j6YdcaVfxdbDDFuYMa}6^{a@MDwL*+6A+rF zB`wyyk!*f5YTutXwr8L7ggbv=0&R$iH{1%2>}>_VQGGtSz79%;)uY@GaG~X@f&fkl zskQgzJjl~PAxp=xCTIB7Cm^Hyq41eV6eMFFO1YGXSJfRt_N(3pqjrgiVLhB=fHkJ; zRl%GlRnGr*aiTH9ZZCyqrrDxLOzYHW{MiS5w=FvtWa$b+L9s6|k1c7y_sHUS31=vv z05L>{MjL~JTzbfrv3sT_jR*5H;GnBMB;R!SEX(g>E!g*+CwQAm{EWkMVFLy{8aC zGdPn7irvva4!<7vSwUIL^RyrkDruw?`A^=jRw3dXrtvGX-#=-41m%r#{66evn@*)14usPf{p#nrAHY>? z-EY}Ee2No za6&_FKd`E}N0B2@BrJRlY(oi~Q?>UC0k^|);?%5$pS@YS=8=q9fOaMZtKz@`*w9ejAK(nFdtV&DK9yNgH1+)*L^9sT*k!x4 zMB5>(^WeQFeB|!~Ejk+#PGhHLiXCT{a`QaYkuQ=!h^$~6x0=<1Bd!oe$0!)jKqn#! z>qLZBqz2{2?HNc;UH>IEYS&&G1Q)<&@DvIC4m_c50m%|lyoTXi_Mq)n>B49J)HEoD zW5$~S_oJeoN$6xtuO8fEi&RaLCs_$~^$7=gC>CMdbSSg!cQzM+%{J2ju~eMVd>r|= zA?B_JR@G9ONsJ>N&^UPC@L__G5Ny?apBXung~*`>IOzd*u=LaJ&RlHy#u&LbrrY)+ zxGq$F)vgCEq2&om!uuK=lWvWosHIuL#)o&C-(r(P0J#0*Mu6L6zEKqj7(2np2%rz7 zY{a4&eDU}d2!tq%aUsg~fG?qabTb4%^y&zFhY1`qScH3v_Ke3 zYBXr;`1CYYcwUx?*85a^JcJa_M52%)Q#PxKAe-kDJ+>-?) z^oNeX&}6FIWj+Y`al*N9T&JrJTqT)+z1S_3w+Uk#&|U(%{rIZm>JaSH-^!cw4iWG$ zw8KY3_1+g`3`yZmO4!mYeX8{~EA--} zgWZp@-LiW1hab*2GwymrlK}GQFnpC(kN|=JNR^W{3%9)Az-?m<@PRnLdQUWk(3dDu zC#lhPe5CTHl^jqR5;2rVWN0$$&@P4tm=FI`w~yn63VOe`AhhGR9rb~d6a%0}BfU+F zdG=Wd=p8agkGbO_&ZQ!#J+var-{OCsT!FL<>S-BgSwz@jKU7MEALO{>w`@G55JEEr z$lHlg6IwnFviQuWhoB*(c6fVzMV~NGBdP*}dZNnl9)-S)ff_|)Np%#c&=49ro}7HP zQ5g(tSmXk#Sg4GW=kgvchc}<)9}Ui}J5``x>`h0=g_^ILr2@ z+bDa>)VhI4O$TYiricyo0BkY)n%%xOuYyLpF(>^0ppi|e5l8K%j7CUAIJUSfKwhK6 zA3+pgLbZ5Y{2Fb0Rnej4p8MuFsCO;)DAfXWX~_wyk_E!qPFeO9{8rDj*L=ATLO}#s zgodyc%R!k&fX9xu zI{>o{A?n1%XonLw51=-p{EzFeAqV}07ws(ezCYz>I4OE$_k$50)Nl{7WxlS4#D5r7 zlaSiy!}=f!itc-*8Ttyi?tTd5=yYDd=P2GAMAblwdIWm6c*)TCsqD9pFQ7kyR>Lyh zZFwF!q$!e|85PCL2>j3I!?1W!r|8o^z%pCZ)X`#!c6ErwLB($9-HEtZx{?#_tGo)v z{+qG;kFik7T(zLhS+*M?1t|bUT7{rUuy)WC#5lv&)i(B~n3Lzm<7LEBYvffR-N8+W zJrOVnvy8fey*26#s;r~)H9{-xBOG&aMhO?c$|e*~06p0?uv!QmLI3!jycTufD_vV` zQde=7S3BrRJT?rHD(pi+X}u0;R9AV&r#eAj0X9g3A({|Ni-7eX=y^v*W~mxwd+sR@ zKGYB#Ufg8J?T-V=U)mn(=oFqt>W+ir4;q{WUwfwL?nk>H){+RpAJ9w;@E00DIy%XL z-z*sUb$Flpc_6+mD}p_m%N4f>jrcCmB)a2dJX%7MxQVaA>vjlM^i%OBs0S(bO*0fge>rMqPGP3=<3iCEeV+NBp-j1|&z9i*a+7JnXo@rwVR z7M7)gH(1JVaKxLn4yz&lWAnP$!NWy|s z7$jjq#D=n#H=j#jV|vz~v2~ibN{|a7RN;m(ND9Egq!ApPyeCIums!GH$z1iFBijoJhgW zRusagvdPX*CubJX@aAZM&k*b`xj_p(C-CYK6e#6on5zJyFfvV|6? z5rC>H5xkNjjX4Ym>f1^3X-qWYs2lV-^Z7N3HER*_b(77OrSSl?F_#+InrZ%2^~ z20gV4k#=oxRDHw`FkzI|1g}#yaal`)D;^doWQ3zX)j_8uDV#lro|oXB$;HY?8!VCE z1{;`~(*m&akN^+_QOs37=d`^ev8=!PTa9h@?}ccQ!;yI#Jp#;4wE4IPLsQv{5pj?R zR769GK&dHU2F=EQz@fC28Y~G&Rn%XuehNK{ zsEI2CUsS&ex}?JB>^H6TOg>Xlc)8+YJhd7Jh5K#8+)*JVtIU`^j5wT`;E*H<0UnT$ zAb%6X9YYesU*6hhsUJ+NEdi>2_`5Ro7hB+6@Scek6ADOF z`(|Ka?L5w|2yvnop2EZXX&sNDNZV?ck6S#om`q1-<7aL-j#lnZOS`#r2WbpgY@f=9 ztrP@MMJ;TCcbFSkx~zNK_JT07Dy1E;(PK^ZaLWcmN>8Hz53Tg5{T8AGN9C$_QnTX| zer~^b;c4cHR`cf84s7o?g+^6AKE4c`(-7g;OAVy>MUYl-&Ttj!v6>tMp-H#b8B6A% zG%a=&QE_o7U%nEvMhG^h)UklO&rA<`A{X zaF&tgM`p6H0N^;2#n~CB8%z2j>j57mON?pw&13=c6|MriL)6hf9;B)~6_<6?=RS{D z+qgT#lQzKoGOZ{iaI@IdmAHvB53A}g&wFEv4bdMbyU5GlN({B;hIWdI0ck{F38}4T zXtHBQw=&VrO*!}>h>Rrevk=ctKT8Io$Vq{ZGTF{`CG`}k--I6y?}t+Cgu;@qpmEfS za7LdG-s!&tUT#3eo9wz9mcz5JjC*4v+FD6j_&?&I#eErU}H^OysC2L zB-HiSxk8QG+rTtCLrKmc5rumG#33U}6Q}j;`oK>set0t99)~8;7iy+7AP5b}_$JP- zv-C!r2*PFC@-{kxvoKaae<}pFto*!Ey5|Y29TGjnc{>43t%=fyt>;j*0sU4Kx~hxW zvK4W29cR~>((T#;lscXp)~eoQbtICA&z2XU9m!0-Rzc2rsmV4@n=rMJiPJr>EaS!$ z{876anqlI1+)sQEC6dZrioKXr5NkKWx1SqbB95i|}IdO2gLSFPv}H;wB2 zvF893SvMU%UI!8Yk`1ce(|>9#0og#Gj_!T)4uEnul)MaD#-hrvlKz~pC%O*L0ka^M>e@5iRY4X z=W{0xpsfreOgoIb zlW!jhxZ9%vHc+kBrZ4Acp3PSMh-s+NE@a5$P@9)7+f0&wv6lg)F%Y@;J2eB-0AQQX zLp)6k<=-;pnQn*&3(NIH=B`;>U;{EA+s7Ioaq{G6;{;v}5gu>~KS{$T#TO^5UR14do15!*;G=h4 zlF4A0U(^@4FVura#>V0~D9Px(DV|zzGxSNRZ9Mbg+~Z;!yG?|Ak!90AHn|E&N=JAe z@Y#>;YA{}sHQK`{t(UEJF~pQYpOJ4o{63ME9P04 z5Tgg2kv>~{`7=RJjXWNjwV|XLF1%$75vDVJb#2f*{r->$4Wm|XqQcAvCEbNyQ~a4@ zWf=n*gDh4kaucL%)0|paA^?d^Br8a4iUe4cR%APUMz(GT@$W_nHrw4-N2G|G5*6Ie z-t}v<(UyjmA<@4*g4 zFZBRUz}%@L-59bbGgX`m(>>w7SiF@m=|V`yd;yn5Z2f~8Fo$uY94v-};Ry?Eh<48| z7><0pWthm9ztSB10F*V{mxZ@ExdD{|FZ%B9{=E?SJ%SXkE(q_eap0Eez()pE54f|p z3*m2)Ro2UlqwF67X%BE&o9}E?D=rlpG~kiB0vZ3dkxc=aUk!^%dnDXJ#7M(82oPTXrbd^Q0)jkHY?lM11#@z=c5cf z4`kjJ+$qC!8nBO)6W53WJ+o-0(jX7Upmnz0C^O zU;5>%WhtbM#mXTr&L>kHgcR%y|D9|JAe-J`W$_QP4T5}cHAb53SbK$Gld|z1eoESj8@^G90?0k%!!yG|s3>V}&WU%R(V8Y^Dnz@>=g`e0gmoI2 zU7i>bpmO!bx!BHM<9e~ovShct#`T5Bnsrg zUJ-3&?8Kuns-Y8CJ+U{= z)w1d~O-DN~8+};MOqAj;WYA^7#{wkMpM7B&O6|5_7m(3k0}46 zAK3F#fWW^`f2?6cXvV84)A*8zsyT|GI2HSnzZXDECDR*n)XnQtENV(MJ5G$K16Us6 z;H~nVSN(Gou#>ui4m+-$^NS7!KcK_?UHX{U8|C4jjnrz9icyCi^IvJcqe1mG|8Gk$ zhdPTM)_hoQfoWJGtRFqMH&X0;VP&V7gO3IaA))MGp@RY$Ku>1Q-UYVnRDX#6i$=tA zL8^oL2i$rl#)`%2)aY`QmvHc5_qEa5t&6W@IHL-etIs-yA zwJyM5Zcmn`6vC?a5JN$*E1ljBt`!Haey&MWjcHhFw%}hDAN!$`ZGfp+q>ahS6-He< zmXp_8X2uBKk&f`m7)-jm`=6qt0VmS*o!k8wA%j^ON3Go}!-RTKiVw`G%BOs&)V2+{ zJ-8#@aROGo~yMOEvq5LG`vC!I})+R z#Un7DI5UyBB^+FMK?;YUcxDO|nl8M4e&v|M@qzn>fa9`rd)+M!@hP>P6=z&mK3l`0 zZI*Sh0IW)Pd7+Nr#mo;W#XR|3SHZRD)J-2#5^wZ}h~@XB-B@NwkLC(WI`^kPq&bt) zZOxC*Rg)Z)gP{M4V@I@DO`$eNjffS7fgB1mK9FntQES^r99-97R{W#=IPWHl+wL!w zA8bQ;Y79bUpyKdPrSKMdM~T+?F4jP2sjijHQiFin{C}vui*lFJfOC#LMcS=Zk~<0mg689YV$IzImh~N2?{C)559$en^};6 zcK6fyn_o7=lvq% z9OdWm0RaOiD4A)pRF+1rPmZPTWjJF?gpUpVv7kP#F(a?4&^!N)fuowj7UPM#Z9&1h zRllqNuy!G*nOrM$=;YtCfESg!niDPvH??nj7a#CGR(z_*aNX<8=Rrbhr77t8_eCk@ zuf!V*p*Z&9te8)4yv>SvMp1GH8{z7PpfCX`%zlJ0k>ZE62uU=R!tVd_D zUP_W_o~A{jZpjkwX3XsDF~_pjkm?9&%6>KdD#GvqirNB!+lZGZ! zJo}h%GE7k?iJ(%NCd*BsQl|6rt;Dp^qJ3mUZWluB$f!`5| z+F0oA^4JxN2(j@aW*hKh&-^#2{sL(0ytKsdz1ZG?h~L6P$>CaQK%fc_=z4#CF$7vmaQnIMx1vc#BX?vR~#$?f`SGH z4*lIJ)*NXAth(y$3$oajB2^Nkc#%T>K@_~aK@vAY0Ke7)d9QK}3%R8q!i7<6FGDBA z5IJfr$faW;Sw{OL1yD&Qj>1vb!jQ_*Zf<_DSkt!Hh^#2;i{y5xNh1P?uSbW1f197&K`7X;Q`A~k-z!QuNF%k zaiinh1H^#*k>A-fqNztfNQj=}9DkQ6Gd@e@}YJeLi%YQW%gLM{Ppqga+nx;f8S z^61d!1xbw=_9;hS>#RFXhns*C!h_)g3{-X$RT9cSF!5~^0fcmle982-zcwZMk9Wkz zxCXx6>F9vr5DJTtjh|Olj_Psu2E#EQtNb9QIz40Nb7Hqs;Q_}WDE*iKm+wZSBqO-< z^o(z(oNnZ2K$E}4ZO}$s29sBj(6p0{KBS>3RtRj#!pble^N#sY4^)eudbchoWUAly z1r&7!j9NNY7Ug#1ySvgUC%A*)AEUljqaY0EHns22T+(e;9jz+j!XYMvv zhq#FX2Y+u9Br(LzFrlbxs~w|W|Abt6nd>f5y5Bx7&KY@L@K_ezLR+r@bpyvO znY)HdrHw z-Q#dZ{gBqQlzmDPgWt+1H01|vYlHjh6J7V0HIeF20{dv`kJ5E0vmWelFTJtmlIbx7 zo(s;rV2xDACYZOW!?WpgvzzNm_`EyyG)mZIF|3xKvUWj~%HyF5-%f5h+TCznt&&eN zs>Xq#Jv~s}1XYgjx9LH3P_DcAJ8J!SJW?m@d>}IGYJLG@Zy z&ajT1AU!Z{W8jgk+4%R;Bq|wtHOnZPW|Jbc5?F43Ha8F{5$PLxuaG?rT~Ogz)YAY} zj=;-cfhwp4O-P=nrEKh0=)DWquxzywSgAEmJt=Yr~lcyvoai(adppI&9F=?g9 z5*DrnRDMV0CE+BLUr5e-wax-+s0W8x)*UNcAbyMpM!%UO2TJ)ON1JIbulb18y-5O< zq=*0of47A-+H(h(v3QMG82jgg_;gVt&t}z42#!n{gDvCX7Pg%i%`O}nVIu+PB`dT7 zAC{McMa)D5L4_4~uJ}Tm%jD4VQ1m(eYd+iO>ejI6nJMGY)hu{ycFh0xU5(ESzPIpN zxgo7P}=M z2J94)pdh3#6$OO_{PllT!&~52XFtTU+4n>gmi_Z#e;iB`&NyLK9+(frDEOL2?q@so zQaa(qN<(+#29<{cgUy*8+gVb?{1x>o{7UlJUbgNp0H8|n=$B$}#zB;SKTE4&;s_00 zfD?uwxiyH5GHMYtGA!^G$xj&YLujWxvp(71N&uZS39gQ8-S2{prt}GzHAVRkQ}y5JVO!4f z|39avo5{sZj#-JTs`tTz&+u@Iw1*3oPkM)$tSynedpGzr4)5iiyLEEn zyg}1?zLXxoqV^2dP}FeE&CR_(zIOC}`?j{*I?CMOuKG&8C!;xN8R-eG->@M~cO+$= zv67OKxl!1-S`Vrn#S|>`fCsJ4qqawxt*=@Y$_bM?Ut;h0C&=pBu_|{3yr-^m=+L37 z&&p2PrmX6o{PO-0S?g-UvCaRW5zhl_M(C+MQUNUay@A_sHO9g?ZkufH&z~Ew)V!{P zd(2zg+AeedjNM|?J{s>Z8)klHy*@^8w9?1R;?Uh3;R;s0qjIO@fWeKvQl45TRQ_T zw;TBRIB1GqlNj@DP^xwp<>#5{2W6X@#l8#-{8^B&3x9Ccz1tR>oSaNj?r!&!vYL)7 zJdu-~ZI?JP;Y&O5h;2*^jj{ur(S5CYV=NF8d|JMR(2yeC9sOHhbkq?wg~a5@vL?AQ z*O~Y>%jx&}RBznG!xNL=y@k?mRmE;y>C^uBrlEocq0PvhPP_Z_INu5+k00-zkg_^? zu0J~RTfezsu|VFsUq{Oe`YoShYpyl51SsC+BBKWrB>ss4jTuc5`l7y=V!2qRj`%S z)YyTE6ty}tzmi|Y!T~^?H2s?~!R(^!NGW?_Xl~FqkgDDC_T$H$K{L}+Ek~5*QiV@s)+Tu_bq#1`wspHzk=IXjpZvZ|DE$?qm8TG-hChW ztLEnSL(q6%e=B`zdRxE4?ef+5X+GBPqU`tiwm zUteGK==Xf*pNxL%ewklbs2M$`%w`bHu2fPUOwg+!r(XisX9UNmr;gLdhj)ucR9*RA zR$7|i`uJF+xbBI!J;lQRaE`->-2I`Uyu1Po8~*nQ2{QM}$`ZeS|6bSKy?0e`PG%rbJF0?ap*zW8siP*y#{^xgSa4kp&oklycwhl@)o{8MDQ6r8m zUcod8dg6f5&9dpg9MmiwJ`4@1b-UNSdGqFq|Js#&8N@mu>q`4qGxix_O-&5Ac@_I} znD|kamC-{h-?P?u!GZ<7?;iN{j*pKg2DQP8h!EE?iICW2K6P>?vAs+6AF~DHs?`Na z{r>7{INR()U!?u`BWk@>5fZlYy`!V~#Uox5)pzdx;coeU!{yNrf6UuVd%ewd)jtW0 z1bbG>!tLunzxkI>L=nDiSp%w1%NpK)evkqqP(Puxoz1}c&p%Q}Yeg-!`+w3fK@Z3X z+ZbHJc8X!~^`AX>IDqB7(-Q7^`p@soesuxJ5DcUTF>@6E_tezh1NnGDz4mWH{Hs+- zK+G+laj0AqtD*6uodfO literal 0 HcmV?d00001 diff --git a/Packs/CortexXDR/doc_files/Cortex_XDR_Alerts_Handling_v2.png b/Packs/CortexXDR/doc_files/Cortex_XDR_Alerts_Handling_v2.png index dc081b4e760f19eee362306acbaf6ad9265ebd6b..296bd151449e7244ff5300760493d7aa43fef1d0 100644 GIT binary patch literal 222454 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%0Dp?JQ!dot|Gwp1`o0u-2vstQT- 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

    578x- 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 T*4efM{yTQ$ Date: Sun, 3 Mar 2024 16:19:19 +0200 Subject: [PATCH 132/272] Update Docker Image To demisto/auth-utils (#33194) * Updated Metadata Of Pack Cylance_Protect * Added release notes to pack Cylance_Protect * Packs/Cylance_Protect/Integrations/Cylance_Protect_v2/Cylance_Protect_v2.yml Docker image update * Updated Metadata Of Pack Zoom * Added release notes to pack Zoom * Packs/Zoom/Integrations/ZoomEventCollector/ZoomEventCollector.yml Docker image update * Updated Metadata Of Pack Silverfort * Added release notes to pack Silverfort * Packs/Silverfort/Integrations/Silverfort/Silverfort.yml Docker image update * Updated Metadata Of Pack Box * Added release notes to pack Box * Packs/Box/Integrations/BoxEventsCollector/BoxEventsCollector.yml Docker image update * Packs/Box/Integrations/BoxV2/BoxV2.yml Docker image update * Updated Metadata Of Pack Troubleshoot * Added release notes to pack Troubleshoot * Packs/Troubleshoot/Scripts/CertificatesTroubleshoot/CertificatesTroubleshoot.yml Docker image update --- .../Integrations/BoxEventsCollector/BoxEventsCollector.yml | 2 +- Packs/Box/Integrations/BoxV2/BoxV2.yml | 2 +- Packs/Box/ReleaseNotes/3_1_43.md | 5 +++++ Packs/Box/pack_metadata.json | 2 +- .../Integrations/Cylance_Protect_v2/Cylance_Protect_v2.yml | 2 +- Packs/Cylance_Protect/ReleaseNotes/1_1_34.md | 3 +++ Packs/Cylance_Protect/pack_metadata.json | 2 +- Packs/Silverfort/Integrations/Silverfort/Silverfort.yml | 2 +- Packs/Silverfort/ReleaseNotes/2_0_25.md | 3 +++ Packs/Silverfort/pack_metadata.json | 2 +- Packs/Troubleshoot/ReleaseNotes/2_0_19.md | 4 ++++ .../CertificatesTroubleshoot/CertificatesTroubleshoot.yml | 2 +- Packs/Troubleshoot/pack_metadata.json | 2 +- .../Integrations/ZoomEventCollector/ZoomEventCollector.yml | 2 +- Packs/Zoom/ReleaseNotes/1_6_9.md | 3 +++ Packs/Zoom/pack_metadata.json | 2 +- 16 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 Packs/Box/ReleaseNotes/3_1_43.md create mode 100644 Packs/Cylance_Protect/ReleaseNotes/1_1_34.md create mode 100644 Packs/Silverfort/ReleaseNotes/2_0_25.md create mode 100644 Packs/Troubleshoot/ReleaseNotes/2_0_19.md create mode 100644 Packs/Zoom/ReleaseNotes/1_6_9.md diff --git a/Packs/Box/Integrations/BoxEventsCollector/BoxEventsCollector.yml b/Packs/Box/Integrations/BoxEventsCollector/BoxEventsCollector.yml index f56068fecc51..486bf1c44f18 100644 --- a/Packs/Box/Integrations/BoxEventsCollector/BoxEventsCollector.yml +++ b/Packs/Box/Integrations/BoxEventsCollector/BoxEventsCollector.yml @@ -57,7 +57,7 @@ script: defaultValue: 3 days description: Get events. name: box-get-events - dockerimage: demisto/auth-utils:1.0.0.87472 + dockerimage: demisto/auth-utils:1.0.0.88531 runonce: false script: '-' subtype: python3 diff --git a/Packs/Box/Integrations/BoxV2/BoxV2.yml b/Packs/Box/Integrations/BoxV2/BoxV2.yml index f8c7236d3f28..63568855f6eb 100644 --- a/Packs/Box/Integrations/BoxV2/BoxV2.yml +++ b/Packs/Box/Integrations/BoxV2/BoxV2.yml @@ -2496,7 +2496,7 @@ script: - contextPath: Box.Folder.item_status description: The status of the parent of the item. type: String - dockerimage: demisto/auth-utils:1.0.0.87472 + dockerimage: demisto/auth-utils:1.0.0.88531 isfetch: true runonce: false script: '-' diff --git a/Packs/Box/ReleaseNotes/3_1_43.md b/Packs/Box/ReleaseNotes/3_1_43.md new file mode 100644 index 000000000000..08bc52942a03 --- /dev/null +++ b/Packs/Box/ReleaseNotes/3_1_43.md @@ -0,0 +1,5 @@ +#### Integrations +##### Box Event Collector +- Updated the Docker image to: *demisto/auth-utils:1.0.0.88531*. +##### Box v2 +- Updated the Docker image to: *demisto/auth-utils:1.0.0.88531*. diff --git a/Packs/Box/pack_metadata.json b/Packs/Box/pack_metadata.json index eaae58d22a2a..09f60d373052 100644 --- a/Packs/Box/pack_metadata.json +++ b/Packs/Box/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Box", "description": "Manage Box users", "support": "xsoar", - "currentVersion": "3.1.42", + "currentVersion": "3.1.43", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Cylance_Protect/Integrations/Cylance_Protect_v2/Cylance_Protect_v2.yml b/Packs/Cylance_Protect/Integrations/Cylance_Protect_v2/Cylance_Protect_v2.yml index 180e91e2baeb..7bc09aca70a4 100644 --- a/Packs/Cylance_Protect/Integrations/Cylance_Protect_v2/Cylance_Protect_v2.yml +++ b/Packs/Cylance_Protect/Integrations/Cylance_Protect_v2/Cylance_Protect_v2.yml @@ -968,7 +968,7 @@ script: - contextPath: InstaQuery.List description: The list of InstaQuery. type: string - dockerimage: demisto/auth-utils:1.0.0.87472 + dockerimage: demisto/auth-utils:1.0.0.88531 isfetch: true script: '' subtype: python3 diff --git a/Packs/Cylance_Protect/ReleaseNotes/1_1_34.md b/Packs/Cylance_Protect/ReleaseNotes/1_1_34.md new file mode 100644 index 000000000000..1ef6ed48d92a --- /dev/null +++ b/Packs/Cylance_Protect/ReleaseNotes/1_1_34.md @@ -0,0 +1,3 @@ +#### Integrations +##### Cylance Protect v2 +- Updated the Docker image to: *demisto/auth-utils:1.0.0.88531*. diff --git a/Packs/Cylance_Protect/pack_metadata.json b/Packs/Cylance_Protect/pack_metadata.json index a4576343e287..b8788fdb2028 100644 --- a/Packs/Cylance_Protect/pack_metadata.json +++ b/Packs/Cylance_Protect/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cylance Protect", "description": "Manage Endpoints using Cylance protect", "support": "xsoar", - "currentVersion": "1.1.33", + "currentVersion": "1.1.34", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Silverfort/Integrations/Silverfort/Silverfort.yml b/Packs/Silverfort/Integrations/Silverfort/Silverfort.yml index 324a75ed89a6..bf691ae8f6b6 100755 --- a/Packs/Silverfort/Integrations/Silverfort/Silverfort.yml +++ b/Packs/Silverfort/Integrations/Silverfort/Silverfort.yml @@ -117,7 +117,7 @@ script: required: true description: Update the resource entity risk. name: silverfort-update-resource-risk - dockerimage: demisto/auth-utils:1.0.0.87472 + dockerimage: demisto/auth-utils:1.0.0.88531 runonce: false script: '-' subtype: python3 diff --git a/Packs/Silverfort/ReleaseNotes/2_0_25.md b/Packs/Silverfort/ReleaseNotes/2_0_25.md new file mode 100644 index 000000000000..b09341a44308 --- /dev/null +++ b/Packs/Silverfort/ReleaseNotes/2_0_25.md @@ -0,0 +1,3 @@ +#### Integrations +##### Silverfort +- Updated the Docker image to: *demisto/auth-utils:1.0.0.88531*. diff --git a/Packs/Silverfort/pack_metadata.json b/Packs/Silverfort/pack_metadata.json index 0ecd2462d232..c99c491a700b 100644 --- a/Packs/Silverfort/pack_metadata.json +++ b/Packs/Silverfort/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Silverfort", "description": "Silverfort protects organizations from data breaches by delivering strong authentication across entire corporate networks and cloud environments, without requiring any modifications to endpoints or servers. Using patent-pending technology, Silverfort's agentless approach enables multi-factor authentication and AI-driven adaptive authentication even for systems that don’t support it today, including proprietary systems, critical infrastructure, shared folders, IoT devices, and more. Use Silverfort integration to get & update Silverfort risk severity. This integration was integrated and tested with Silverfort version 2.12.", "support": "partner", - "currentVersion": "2.0.24", + "currentVersion": "2.0.25", "author": "Silverfort", "url": "https://support.silverfort.com/", "email": "support@silverfort.com", diff --git a/Packs/Troubleshoot/ReleaseNotes/2_0_19.md b/Packs/Troubleshoot/ReleaseNotes/2_0_19.md new file mode 100644 index 000000000000..5bfe55be5c59 --- /dev/null +++ b/Packs/Troubleshoot/ReleaseNotes/2_0_19.md @@ -0,0 +1,4 @@ + +#### Scripts +##### CertificatesTroubleshoot +- Updated the Docker image to: *demisto/auth-utils:1.0.0.88531*. \ No newline at end of file diff --git a/Packs/Troubleshoot/Scripts/CertificatesTroubleshoot/CertificatesTroubleshoot.yml b/Packs/Troubleshoot/Scripts/CertificatesTroubleshoot/CertificatesTroubleshoot.yml index 5f020a19e424..14bfb7769435 100644 --- a/Packs/Troubleshoot/Scripts/CertificatesTroubleshoot/CertificatesTroubleshoot.yml +++ b/Packs/Troubleshoot/Scripts/CertificatesTroubleshoot/CertificatesTroubleshoot.yml @@ -337,7 +337,7 @@ tags: - Utility timeout: '0' type: python -dockerimage: demisto/auth-utils:1.0.0.87472 +dockerimage: demisto/auth-utils:1.0.0.88531 runas: DBotWeakRole tests: - No tests (auto formatted) diff --git a/Packs/Troubleshoot/pack_metadata.json b/Packs/Troubleshoot/pack_metadata.json index d32f6c66be5b..b018be4729e1 100644 --- a/Packs/Troubleshoot/pack_metadata.json +++ b/Packs/Troubleshoot/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Troubleshoot", "description": "Use this pack to troubleshoot your environment.", "support": "xsoar", - "currentVersion": "2.0.18", + "currentVersion": "2.0.19", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Zoom/Integrations/ZoomEventCollector/ZoomEventCollector.yml b/Packs/Zoom/Integrations/ZoomEventCollector/ZoomEventCollector.yml index d95beda9f966..551cb5964e59 100644 --- a/Packs/Zoom/Integrations/ZoomEventCollector/ZoomEventCollector.yml +++ b/Packs/Zoom/Integrations/ZoomEventCollector/ZoomEventCollector.yml @@ -60,7 +60,7 @@ script: defaultValue: 300 description: Gets events from Zoom. name: zoom-get-events - dockerimage: demisto/auth-utils:1.0.0.87472 + dockerimage: demisto/auth-utils:1.0.0.88531 isfetchevents: true script: '-' subtype: python3 diff --git a/Packs/Zoom/ReleaseNotes/1_6_9.md b/Packs/Zoom/ReleaseNotes/1_6_9.md new file mode 100644 index 000000000000..7b8bd225b7d1 --- /dev/null +++ b/Packs/Zoom/ReleaseNotes/1_6_9.md @@ -0,0 +1,3 @@ +#### Integrations +##### Zoom Event Collector +- Updated the Docker image to: *demisto/auth-utils:1.0.0.88531*. diff --git a/Packs/Zoom/pack_metadata.json b/Packs/Zoom/pack_metadata.json index 537cab89e4e7..1f0ae9ba0a1e 100644 --- a/Packs/Zoom/pack_metadata.json +++ b/Packs/Zoom/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Zoom", "description": "Use the Zoom integration manage your Zoom users and meetings", "support": "xsoar", - "currentVersion": "1.6.8", + "currentVersion": "1.6.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 08d8d9800fadc3fcbdc3502da172c7b3a03ae58a Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:20:04 +0200 Subject: [PATCH 133/272] Update Docker Image To demisto/opnsense (#33196) * Updated Metadata Of Pack OPNSense * Added release notes to pack OPNSense * Packs/OPNSense/Integrations/OPNSense/OPNSense.yml Docker image update --- Packs/OPNSense/Integrations/OPNSense/OPNSense.yml | 2 +- Packs/OPNSense/ReleaseNotes/1_0_24.md | 3 +++ Packs/OPNSense/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/OPNSense/ReleaseNotes/1_0_24.md diff --git a/Packs/OPNSense/Integrations/OPNSense/OPNSense.yml b/Packs/OPNSense/Integrations/OPNSense/OPNSense.yml index 0fed2540758d..4964f3fb7546 100644 --- a/Packs/OPNSense/Integrations/OPNSense/OPNSense.yml +++ b/Packs/OPNSense/Integrations/OPNSense/OPNSense.yml @@ -958,7 +958,7 @@ script: description: Rollback revision. description: Revert config to given savepoint. outputs: [] - dockerimage: demisto/opnsense:1.0.0.87396 + dockerimage: demisto/opnsense:1.0.0.88907 subtype: python3 fromversion: 6.0.0 tests: diff --git a/Packs/OPNSense/ReleaseNotes/1_0_24.md b/Packs/OPNSense/ReleaseNotes/1_0_24.md new file mode 100644 index 000000000000..ff4d6fa8e817 --- /dev/null +++ b/Packs/OPNSense/ReleaseNotes/1_0_24.md @@ -0,0 +1,3 @@ +#### Integrations +##### OPNSense +- Updated the Docker image to: *demisto/opnsense:1.0.0.88907*. diff --git a/Packs/OPNSense/pack_metadata.json b/Packs/OPNSense/pack_metadata.json index 6e16ae135f02..9eee26d944c5 100644 --- a/Packs/OPNSense/pack_metadata.json +++ b/Packs/OPNSense/pack_metadata.json @@ -2,7 +2,7 @@ "name": "OPNSense", "description": "Manage OPNsense Firewall", "support": "partner", - "currentVersion": "1.0.23", + "currentVersion": "1.0.24", "author": "SecInfra", "url": "http://secinfra.fr", "email": "support@secinfra.fr", From d62cba27038f9fcacd0c4a32722ad8a3c2caee73 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:36:14 +0200 Subject: [PATCH 134/272] Update Docker Image To demisto/ippysocks-py3 (#33176) * Updated Metadata Of Pack Whois * Added release notes to pack Whois * Packs/Whois/Integrations/Whois/Whois.yml Docker image update --- Packs/Whois/Integrations/Whois/Whois.yml | 2 +- Packs/Whois/ReleaseNotes/1_5_10.md | 3 +++ Packs/Whois/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/Whois/ReleaseNotes/1_5_10.md diff --git a/Packs/Whois/Integrations/Whois/Whois.yml b/Packs/Whois/Integrations/Whois/Whois.yml index d55a915b4d83..c5ce86fd9d14 100644 --- a/Packs/Whois/Integrations/Whois/Whois.yml +++ b/Packs/Whois/Integrations/Whois/Whois.yml @@ -582,7 +582,7 @@ script: - contextPath: DBotScore.Reliability description: Reliability of the source providing the intelligence data. type: String - dockerimage: demisto/ippysocks-py3:1.0.0.87742 + dockerimage: demisto/ippysocks-py3:1.0.0.88715 runonce: false script: '-' subtype: python3 diff --git a/Packs/Whois/ReleaseNotes/1_5_10.md b/Packs/Whois/ReleaseNotes/1_5_10.md new file mode 100644 index 000000000000..026ca652e2c7 --- /dev/null +++ b/Packs/Whois/ReleaseNotes/1_5_10.md @@ -0,0 +1,3 @@ +#### Integrations +##### Whois +- Updated the Docker image to: *demisto/ippysocks-py3:1.0.0.88715*. diff --git a/Packs/Whois/pack_metadata.json b/Packs/Whois/pack_metadata.json index c6d228e65522..9a87dc4866e4 100644 --- a/Packs/Whois/pack_metadata.json +++ b/Packs/Whois/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Whois", "description": "This Content Pack helps you run Whois commands as playbook tasks or real-time actions within Cortex XSOAR to obtain valuable domain metadata.", "support": "xsoar", - "currentVersion": "1.5.9", + "currentVersion": "1.5.10", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e4f4096c292855c4ee67a80f04f3fbb1631403da Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:40:44 +0200 Subject: [PATCH 135/272] Update Docker Image To demisto/tesseract (#33177) * Updated Metadata Of Pack ImageOCR * Added release notes to pack ImageOCR * Packs/ImageOCR/Integrations/ImageOCR/ImageOCR.yml Docker image update --- Packs/ImageOCR/Integrations/ImageOCR/ImageOCR.yml | 2 +- Packs/ImageOCR/ReleaseNotes/1_1_28.md | 3 +++ Packs/ImageOCR/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/ImageOCR/ReleaseNotes/1_1_28.md diff --git a/Packs/ImageOCR/Integrations/ImageOCR/ImageOCR.yml b/Packs/ImageOCR/Integrations/ImageOCR/ImageOCR.yml index 18b269d010d1..8db9968bca7b 100644 --- a/Packs/ImageOCR/Integrations/ImageOCR/ImageOCR.yml +++ b/Packs/ImageOCR/Integrations/ImageOCR/ImageOCR.yml @@ -42,7 +42,7 @@ script: - contextPath: File.Text description: Extracted text from the passed image file. type: String - dockerimage: demisto/tesseract:1.0.0.87375 + dockerimage: demisto/tesseract:1.0.0.88758 runonce: false script: '-' type: python diff --git a/Packs/ImageOCR/ReleaseNotes/1_1_28.md b/Packs/ImageOCR/ReleaseNotes/1_1_28.md new file mode 100644 index 000000000000..c0a8af03e1a5 --- /dev/null +++ b/Packs/ImageOCR/ReleaseNotes/1_1_28.md @@ -0,0 +1,3 @@ +#### Integrations +##### Image OCR +- Updated the Docker image to: *demisto/tesseract:1.0.0.88758*. diff --git a/Packs/ImageOCR/pack_metadata.json b/Packs/ImageOCR/pack_metadata.json index 775084fd84c1..09ab7d6c413c 100644 --- a/Packs/ImageOCR/pack_metadata.json +++ b/Packs/ImageOCR/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Image OCR", "description": "Extracts text from images.", "support": "xsoar", - "currentVersion": "1.1.27", + "currentVersion": "1.1.28", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 262edfb3f918a99f4bba0cd1771d1a46472e211e Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:49:07 +0200 Subject: [PATCH 136/272] update domaintools dependency (#33114) (#33183) Co-authored-by: Wesley Agena --- Packs/Whois/pack_metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Packs/Whois/pack_metadata.json b/Packs/Whois/pack_metadata.json index 9a87dc4866e4..33db3dd3062e 100644 --- a/Packs/Whois/pack_metadata.json +++ b/Packs/Whois/pack_metadata.json @@ -18,9 +18,9 @@ "useCases": [], "keywords": [], "dependencies": { - "DomainTools": { + "DomainTools_Iris": { "mandatory": false, - "display_name": "DomainTools" + "display_name": "DomainTools Iris" }, "CommonScripts": { "mandatory": true, From 11e57fa121e386698d6ba015fbfc786609ae6d7d Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 17:01:20 +0200 Subject: [PATCH 137/272] [ASM] EXPANDR-8305: SO Bug fix (#33181) * [ASM] EXPANDR-8305: SO Bug fix (#33085) * plays * RN * Update Packs/CortexAttackSurfaceManagement/ReleaseNotes/1_7_30.md --------- Co-authored-by: johnnywilkes <32227961+johnnywilkes@users.noreply.github.com> Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> --- .../Cortex_ASM_-_Service_Ownership.yml | 67 +++++++++++------- .../ReleaseNotes/1_7_30.md | 6 ++ .../Cortex_ASM_-_Service_Ownership.png | Bin 118768 -> 116653 bytes .../pack_metadata.json | 2 +- 4 files changed, 48 insertions(+), 27 deletions(-) create mode 100644 Packs/CortexAttackSurfaceManagement/ReleaseNotes/1_7_30.md diff --git a/Packs/CortexAttackSurfaceManagement/Playbooks/Cortex_ASM_-_Service_Ownership.yml b/Packs/CortexAttackSurfaceManagement/Playbooks/Cortex_ASM_-_Service_Ownership.yml index fb040785ce74..69bd5e4c0cd1 100644 --- a/Packs/CortexAttackSurfaceManagement/Playbooks/Cortex_ASM_-_Service_Ownership.yml +++ b/Packs/CortexAttackSurfaceManagement/Playbooks/Cortex_ASM_-_Service_Ownership.yml @@ -43,10 +43,10 @@ tasks: version: -1 name: Normalize and rank likely service owners description: Recommend most likely service owners from those surfaced by Cortex ASM Enrichment. - scriptName: RankServiceOwners type: regular iscommand: false brand: "" + script: RankServiceOwners nexttasks: '#none#': - "10" @@ -99,10 +99,10 @@ tasks: description: |- Automation used to more easily populate a grid field. This is necessary when you want to assign certain values as static or if you have context paths that you will assign to different values as well. Example of command: `!GridFieldSetup keys=ip,src val1=${AWS.EC2.Instances.NetworkInterfaces.PrivateIpAddress} val2="AWS" gridfiled="gridfield"` - scriptName: GridFieldSetup type: regular iscommand: false brand: "" + script: GridFieldSetup nexttasks: '#none#': - "17" @@ -169,55 +169,71 @@ tasks: isautoswitchedtoquietmode: false "9": id: "9" - taskid: 82e4d1d4-d7bc-4a1a-894a-698786adcdc5 + taskid: 5505de94-3fde-4947-86d2-7e95c050fa14 type: condition task: - id: 82e4d1d4-d7bc-4a1a-894a-698786adcdc5 + id: 5505de94-3fde-4947-86d2-7e95c050fa14 version: -1 - name: Is asmserviceowner populated? - description: Determines if the asmserviceowner field exists and if the common fields within it also exists. + name: Is asmserviceowner or asmserviceownerunrankedraw populated? + description: Determines if the asmserviceowner or asmserviceownerunrankedraw fields have been populated to continue. type: condition iscommand: false brand: "" nexttasks: '#default#': - "10" - "yes": + service owner: - "7" + unranked raw: + - "17" separatecontext: false conditions: - - label: "yes" + - label: "service owner" condition: - - operator: isNotEmpty left: value: - complex: - root: alert - accessor: asmserviceowner + simple: alert.asmserviceowner iscontext: true right: value: {} - - operator: isNotEmpty left: value: - complex: - root: alert.asmserviceowner - accessor: email + simple: alert.asmserviceowner.email iscontext: true - - operator: isNotEmpty left: value: - complex: - root: alert.asmserviceowner - accessor: name + simple: alert.asmserviceowner.name iscontext: true - - operator: isNotEmpty left: value: - complex: - root: alert.asmserviceowner - accessor: source + simple: alert.asmserviceowner.source iscontext: true + - condition: + - - left: + iscontext: true + value: + simple: alert.asmserviceownerunrankedraw + operator: isNotEmpty + - - left: + iscontext: true + value: + simple: alert.asmserviceownerunrankedraw.email + operator: isNotEmpty + - - left: + iscontext: true + value: + simple: alert.asmserviceownerunrankedraw.name + operator: isNotEmpty + - - left: + iscontext: true + value: + simple: alert.asmserviceownerunrankedraw.source + operator: isNotEmpty + label: unranked raw continueonerrortype: "" view: |- { @@ -410,17 +426,17 @@ tasks: isautoswitchedtoquietmode: false "19": id: "19" - taskid: 6b8a094c-a54f-4678-86c6-6baf66e29721 + taskid: d1039ef2-c791-4853-8367-d50fe11c8517 type: regular task: - id: 6b8a094c-a54f-4678-86c6-6baf66e29721 + id: d1039ef2-c791-4853-8367-d50fe11c8517 version: -1 name: Look up project owners for service account description: Parse a GCP service account email for the project name, then lookup project owners and add them to a list of potential service owners for ranking. - scriptName: GetProjectOwners type: regular iscommand: false brand: "" + script: GetProjectOwners nexttasks: '#none#': - "6" @@ -429,8 +445,7 @@ tasks: complex: root: ASM.ExternalService.externally_detected_providers owners: - complex: - root: alert.asmserviceownerunrankedraw + simple: ${alert.asmserviceownerunrankedraw} separatecontext: false continueonerrortype: "" view: |- @@ -453,7 +468,7 @@ view: |- "15_10_#default#": 0.2, "17_10_#default#": 0.2, "9_10_#default#": 0.33, - "9_7_yes": 0.55 + "9_7_service owner": 0.55 }, "paper": { "dimensions": { diff --git a/Packs/CortexAttackSurfaceManagement/ReleaseNotes/1_7_30.md b/Packs/CortexAttackSurfaceManagement/ReleaseNotes/1_7_30.md new file mode 100644 index 000000000000..00d330aaa882 --- /dev/null +++ b/Packs/CortexAttackSurfaceManagement/ReleaseNotes/1_7_30.md @@ -0,0 +1,6 @@ + +#### Playbooks + +##### Cortex ASM - Service Ownership + +- Fixed an issue where *service owner* field wasn't always getting set. diff --git a/Packs/CortexAttackSurfaceManagement/doc_files/Cortex_ASM_-_Service_Ownership.png b/Packs/CortexAttackSurfaceManagement/doc_files/Cortex_ASM_-_Service_Ownership.png index 05793efbe6eac190b1fc96ccf344bdf25b3bf023..fe42024acfe9c20578a60103707962ddfa37f5f8 100644 GIT binary patch literal 116653 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

    QWQ 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

    Rn>K}gdY3rO-a!VZS=?hwiPFmCv++Rpq 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

    3f9EA6p7})n*rX;@-WQFi+|$rR~ir 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 literal 0 HcmV?d00001 diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/e2.xlsx b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/e2.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..3fc536b83572342c67a2f81d7412a7c39abc3d12 GIT binary patch literal 16370 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 w{@wRN2>&qP?``sbSMb*~_;&^L-~OLtkGvGOV literal 0 HcmV?d00001 diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/e3.xlsx b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/e3.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..8589c2d77791e4b058a1f67a63c2436a3462427d GIT binary patch literal 16511 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 jg1@K1e=2DE{(l{Nq&`<^YGqpf?@ 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 literal 0 HcmV?d00001 diff --git a/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/p2.pptx b/Packs/CommonScripts/Scripts/ExtractHyperlinksFromOfficeFiles/test_data/p2.pptx new file mode 100644 index 0000000000000000000000000000000000000000..31d0919dc2d148fe00d5b6aeef31c12396dd93d8 GIT binary patch literal 42406 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 Date: Mon, 26 Feb 2024 21:06:04 +0200 Subject: [PATCH 098/272] taxii2serverperformancetest - add server configuration (#32713) * add lines * fixes * Update configure_and_test_integration_instances.py * Update TAXII2Server.py * update docker * revert changes --- .../TAXIIServer/Integrations/TAXII2Server/TAXII2Server.yml | 2 +- Packs/TAXIIServer/ReleaseNotes/2_0_56.md | 6 ++++++ Packs/TAXIIServer/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/TAXIIServer/ReleaseNotes/2_0_56.md diff --git a/Packs/TAXIIServer/Integrations/TAXII2Server/TAXII2Server.yml b/Packs/TAXIIServer/Integrations/TAXII2Server/TAXII2Server.yml index e9894e9b41f1..63ad702b4c8e 100644 --- a/Packs/TAXIIServer/Integrations/TAXII2Server/TAXII2Server.yml +++ b/Packs/TAXIIServer/Integrations/TAXII2Server/TAXII2Server.yml @@ -149,7 +149,7 @@ script: - contextPath: TAXIIServer.ServerInfo.description description: The server description. type: String - dockerimage: demisto/flask-nginx:1.0.0.87473 + dockerimage: demisto/flask-nginx:1.0.0.87872 longRunning: true longRunningPort: true script: '-' diff --git a/Packs/TAXIIServer/ReleaseNotes/2_0_56.md b/Packs/TAXIIServer/ReleaseNotes/2_0_56.md new file mode 100644 index 000000000000..48ef47a5eb20 --- /dev/null +++ b/Packs/TAXIIServer/ReleaseNotes/2_0_56.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### TAXII2 Server + +- Updated the Docker image to: *demisto/flask-nginx:1.0.0.87872*. diff --git a/Packs/TAXIIServer/pack_metadata.json b/Packs/TAXIIServer/pack_metadata.json index 3eba91c83bda..f44590777505 100644 --- a/Packs/TAXIIServer/pack_metadata.json +++ b/Packs/TAXIIServer/pack_metadata.json @@ -2,7 +2,7 @@ "name": "TAXII Server", "description": "This pack provides TAXII Services for system indicators (Outbound feed).", "support": "xsoar", - "currentVersion": "2.0.55", + "currentVersion": "2.0.56", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 2a20b80ffe5c87ef47f0c7c14438fec580846b67 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Wed, 28 Feb 2024 10:51:26 +0200 Subject: [PATCH 099/272] EXPANDR-8024: Additional Azure Remediation Bug Fix and Improvements (#33039) (#33112) * update play * RN * Apply suggestions from code review * update input name --------- Co-authored-by: johnnywilkes <32227961+johnnywilkes@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> Co-authored-by: Moshe Galitzky <112559840+moishce@users.noreply.github.com> --- .../Azure-Enrichment-Remediation/.pack-ignore | 2 + ...e_-_Network_Security_Group_Remediation.yml | 73 +++++++++++++++---- ...twork_Security_Group_Remediation_README.md | 8 +- .../ReleaseNotes/1_1_14.md | 8 ++ .../pack_metadata.json | 2 +- 5 files changed, 73 insertions(+), 20 deletions(-) create mode 100644 Packs/Azure-Enrichment-Remediation/ReleaseNotes/1_1_14.md diff --git a/Packs/Azure-Enrichment-Remediation/.pack-ignore b/Packs/Azure-Enrichment-Remediation/.pack-ignore index e69de29bb2d1..1360511b24c3 100644 --- a/Packs/Azure-Enrichment-Remediation/.pack-ignore +++ b/Packs/Azure-Enrichment-Remediation/.pack-ignore @@ -0,0 +1,2 @@ +[file:Azure_-_Network_Security_Group_Remediation.yml] +ignore=PB106 \ No newline at end of file diff --git a/Packs/Azure-Enrichment-Remediation/Playbooks/Azure_-_Network_Security_Group_Remediation.yml b/Packs/Azure-Enrichment-Remediation/Playbooks/Azure_-_Network_Security_Group_Remediation.yml index fab936c56edf..f65536d152c2 100644 --- a/Packs/Azure-Enrichment-Remediation/Playbooks/Azure_-_Network_Security_Group_Remediation.yml +++ b/Packs/Azure-Enrichment-Remediation/Playbooks/Azure_-_Network_Security_Group_Remediation.yml @@ -2,7 +2,7 @@ id: Azure - Network Security Group Remediation version: -1 name: Azure - Network Security Group Remediation description: |- - This playbook adds new Azure Network Security Groups (NSG) rules to NSGs attached to a NIC. The new rules will give access only to a private IP address range and block traffic that's exposed to the public internet ([using the private IP of the VM as stated in Azure documentation](https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview)). For example, if RDP is exposed to the public internet, this playbook adds new firewall rules that only allows traffic from private IP address and blocks the rest of the RDP traffic. + This playbook adds new Azure Network Security Groups (NSG) rules to NSGs attached to a NIC. The new rules will give access only to a private IP address range and block traffic that's exposed to the public internet ([using the private IP of the VM as stated in Azure documentation](https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview)). For example, if RDP is exposed to the public internet, this playbook adds new firewall rules that only allow traffic from private IP addresses and blocks the rest of the RDP traffic. Conditions and limitations: - Limited to one resource group. @@ -43,10 +43,10 @@ tasks: isautoswitchedtoquietmode: false "1": id: "1" - taskid: e594c0b5-83ff-487e-8a93-e26bff748ea3 + taskid: 1adc8ea1-823e-440b-82da-b83a8d7451d2 type: regular task: - id: e594c0b5-83ff-487e-8a93-e26bff748ea3 + id: 1adc8ea1-823e-440b-82da-b83a8d7451d2 version: -1 name: Retrieve Rules from NSG Associated to Public IP description: List all rules of the specified security groups. @@ -80,6 +80,8 @@ tasks: applyIfEmpty: {} defaultValue: {} operator: SetIfEmpty + using: + simple: ${inputs.InstanceName} separatecontext: false continueonerrortype: "" view: |- @@ -187,10 +189,10 @@ tasks: isautoswitchedtoquietmode: false "22": id: "22" - taskid: 8cc8c11f-23d8-4d25-83ad-c9d0d8142833 + taskid: 8b08e2be-7090-4530-8d81-840e906cbbff type: condition task: - id: 8cc8c11f-23d8-4d25-83ad-c9d0d8142833 + id: 8b08e2be-7090-4530-8d81-840e906cbbff version: -1 name: Does offending rule exist? description: Checks whether the last command returned rules or not. @@ -237,6 +239,14 @@ tasks: value: simple: inputs.RemotePort iscontext: true + - left: + iscontext: true + value: + simple: AzureNSG.Rule.destinationPortRange + operator: isEqualString + right: + value: + simple: '*' - - operator: isEqualString left: value: @@ -425,10 +435,10 @@ tasks: isautoswitchedtoquietmode: false "32": id: "32" - taskid: 56f3b649-2961-479a-8afb-ac0e5919c77b + taskid: b5146806-4b94-4d33-8277-5ea7d3e51bdf type: regular task: - id: 56f3b649-2961-479a-8afb-ac0e5919c77b + id: b5146806-4b94-4d33-8277-5ea7d3e51bdf version: -1 name: Update existing remediation allow rule description: |- @@ -484,6 +494,8 @@ tasks: applyIfEmpty: {} defaultValue: {} operator: SetIfEmpty + using: + simple: ${inputs.InstanceName} separatecontext: false continueonerrortype: "" view: |- @@ -769,10 +781,10 @@ tasks: isautoswitchedtoquietmode: false "37": id: "37" - taskid: cc549549-1a9d-4ae3-8d20-6cf8324b7a00 + taskid: 1a7d4cac-6979-4cf3-8705-ec356925dda6 type: regular task: - id: cc549549-1a9d-4ae3-8d20-6cf8324b7a00 + id: 1a7d4cac-6979-4cf3-8705-ec356925dda6 version: -1 name: Update existing remediation deny rule description: |- @@ -828,6 +840,8 @@ tasks: applyIfEmpty: {} defaultValue: {} operator: SetIfEmpty + using: + simple: ${inputs.InstanceName} separatecontext: false continueonerrortype: "" view: |- @@ -1116,10 +1130,10 @@ tasks: isautoswitchedtoquietmode: false "42": id: "42" - taskid: a3d6d6e8-b01d-418b-8af2-033300d717c7 + taskid: f871b58d-6155-4b03-880a-1889551b6b00 type: regular task: - id: a3d6d6e8-b01d-418b-8af2-033300d717c7 + id: f871b58d-6155-4b03-880a-1889551b6b00 version: -1 name: Add allow rule for port ${inputs.RemotePort} and ${inputs.RemoteProtocol} description: |- @@ -1180,7 +1194,7 @@ tasks: simple: ${inputs.RemoteProtocol} iscontext: true source: - simple: 172.16.0.0/12,10.0.0.0/8,192.168.0.0/16 + simple: ${inputs.RemediationAllowRanges} resource_group_name: complex: root: inputs.ResourceGroup @@ -1197,6 +1211,8 @@ tasks: applyIfEmpty: {} defaultValue: {} operator: SetIfEmpty + using: + simple: ${inputs.InstanceName} separatecontext: false continueonerrortype: "" view: |- @@ -1215,10 +1231,10 @@ tasks: isautoswitchedtoquietmode: false "43": id: "43" - taskid: e5f451a1-edd6-4b06-8b32-c9ad5038de45 + taskid: c98dc204-241c-4c23-8de5-f9e778ac7395 type: regular task: - id: e5f451a1-edd6-4b06-8b32-c9ad5038de45 + id: c98dc204-241c-4c23-8de5-f9e778ac7395 version: -1 name: Set variable for offending rule priority description: Sets variable for the offending rule priority in the list of rules returned. @@ -1253,6 +1269,14 @@ tasks: value: simple: inputs.RemotePort iscontext: true + - left: + iscontext: true + value: + simple: AzureNSG.Rule.destinationPortRange + operator: isEqualString + right: + value: + simple: '*' - - operator: isEqualString left: value: @@ -1326,10 +1350,10 @@ tasks: isautoswitchedtoquietmode: false "44": id: "44" - taskid: 44a359f8-455d-4de4-8beb-a193599922ca + taskid: 76be7dd2-448b-47b5-8ad1-8e5197e74bc8 type: regular task: - id: 44a359f8-455d-4de4-8beb-a193599922ca + id: 76be7dd2-448b-47b5-8ad1-8e5197e74bc8 version: -1 name: Add block rule for port ${inputs.RemotePort} description: |- @@ -1407,6 +1431,8 @@ tasks: applyIfEmpty: {} defaultValue: {} operator: SetIfEmpty + using: + simple: ${inputs.InstanceName} separatecontext: false continueonerrortype: "" view: |- @@ -1663,6 +1689,17 @@ inputs: playbookInputQuery: required: false value: {} +- description: Azure Network Security Groups integration instance to use if you have multiple instances configured (optional). + key: InstanceName + playbookInputQuery: + required: false + value: {} +- description: Comma-separated list of IPv4 network ranges to be used as source addresses for the `remediation-allow-port--` rule to be created. Typically this will be private IP ranges (to allow access within the vnet and bastion hosts) but other networks can be added as needed. + key: RemediationAllowRanges + playbookInputQuery: + required: false + value: + simple: 172.16.0.0/12,10.0.0.0/8,192.168.0.0/16 outputs: - contextPath: remediatedFlag description: Output key to determine if remediation was successfully done. @@ -1682,6 +1719,8 @@ inputSections: - RemotePort - SubscriptionID - ResourceGroup + - InstanceName + - RemediationAllowRanges name: General (Inputs group) outputSections: - description: Generic group for outputs @@ -1689,3 +1728,5 @@ outputSections: outputs: - remediatedFlag - remediatedReason +contentitemexportablefields: + contentitemfields: {} diff --git a/Packs/Azure-Enrichment-Remediation/Playbooks/Azure_-_Network_Security_Group_Remediation_README.md b/Packs/Azure-Enrichment-Remediation/Playbooks/Azure_-_Network_Security_Group_Remediation_README.md index 75fb61f3e50b..8855dd28fd00 100644 --- a/Packs/Azure-Enrichment-Remediation/Playbooks/Azure_-_Network_Security_Group_Remediation_README.md +++ b/Packs/Azure-Enrichment-Remediation/Playbooks/Azure_-_Network_Security_Group_Remediation_README.md @@ -1,4 +1,4 @@ -This playbook adds new Azure Network Security Groups (NSG) rules to NSGs attached to a NIC. The new rules will give access only to a private ip address range and block traffic that's exposed to the public internet ([using the private IP of the VM as stated in Azure documentation](https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview)). For example, if RDP is exposed to the public internet, this playbook adds new firewall rules that only allow traffic from a private IP address and blocks the rest of the RDP traffic. +This playbook adds new Azure Network Security Groups (NSG) rules to NSGs attached to a NIC. The new rules will give access only to a private IP address range and block traffic that's exposed to the public internet ([using the private IP of the VM as stated in Azure documentation](https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview)). For example, if RDP is exposed to the public internet, this playbook adds new firewall rules that only allow traffic from private IP addresses and blocks the rest of the RDP traffic. Conditions and limitations: - Limited to one resource group. @@ -20,14 +20,14 @@ This playbook does not use any sub-playbooks. ### Scripts -* AzureFindAvailableNSGPriorities * Set +* AzureFindAvailableNSGPriorities ### Commands +* azure-nsg-security-rule-update * azure-nsg-security-rule-create * azure-nsg-security-rules-list -* azure-nsg-security-rule-update ## Playbook Inputs @@ -41,6 +41,8 @@ This playbook does not use any sub-playbooks. | RemotePort | The remote port that is publicly exposed. | | Required | | SubscriptionID | The Azure subscription ID \(optional\). | | Optional | | ResourceGroup | The Azure resource group \(optional\). | | Optional | +| InstanceName | Azure Network Security Groups integration instance to use if you have multiple instances configured \(optional\). | | Optional | +| RemediationAllowRanges | Comma-separated list of IPv4 network ranges to be used as source addresses for the \`remediation-allow-port-<port\#>-<tcp\|udp>\` rule to be created. Typically this will be private IP ranges \(to allow access within the vnet and bastion hosts\) but other networks can be added as needed. | 172.16.0.0/12,10.0.0.0/8,192.168.0.0/16 | Optional | ## Playbook Outputs diff --git a/Packs/Azure-Enrichment-Remediation/ReleaseNotes/1_1_14.md b/Packs/Azure-Enrichment-Remediation/ReleaseNotes/1_1_14.md new file mode 100644 index 000000000000..b42b93ff65db --- /dev/null +++ b/Packs/Azure-Enrichment-Remediation/ReleaseNotes/1_1_14.md @@ -0,0 +1,8 @@ + +#### Playbooks + +##### Azure - Network Security Group Remediation + +- Added the *instance_name* optional playbook input to allow users to specify an Azure Network Security Groups integration instance to use. +- Added the *RemediationAllowRanges* optional playbook input to allow users to specify IPv4 network ranges to be used as source addresses for the `remediation-allow-port--` Azure NSG rule to be created. +- Fixed an issue with not being able to detect all offending rules. diff --git a/Packs/Azure-Enrichment-Remediation/pack_metadata.json b/Packs/Azure-Enrichment-Remediation/pack_metadata.json index aa82b6bf2389..88e4b641f5c2 100644 --- a/Packs/Azure-Enrichment-Remediation/pack_metadata.json +++ b/Packs/Azure-Enrichment-Remediation/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Enrichment and Remediation", "description": "Playbooks using multiple Azure content packs for enrichment and remediation purposes", "support": "xsoar", - "currentVersion": "1.1.13", + "currentVersion": "1.1.14", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 9d44496abeaa2ed4625e7ba50e28d3b9088dbc9d Mon Sep 17 00:00:00 2001 From: Jacob Levy <129657918+jlevypaloalto@users.noreply.github.com> Date: Wed, 28 Feb 2024 11:36:09 +0200 Subject: [PATCH 100/272] fix tpb (#33117) --- .../CrowdStrike_Falcon_X_-Test-Detonate_File.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Packs/CrowdStrikeFalconX/TestPlaybooks/CrowdStrike_Falcon_X_-Test-Detonate_File.yml b/Packs/CrowdStrikeFalconX/TestPlaybooks/CrowdStrike_Falcon_X_-Test-Detonate_File.yml index 4bcf197dd68a..de2aeea2ef12 100644 --- a/Packs/CrowdStrikeFalconX/TestPlaybooks/CrowdStrike_Falcon_X_-Test-Detonate_File.yml +++ b/Packs/CrowdStrikeFalconX/TestPlaybooks/CrowdStrike_Falcon_X_-Test-Detonate_File.yml @@ -83,13 +83,13 @@ tasks: - "4" scriptarguments: filename: - simple: "# test.pdf" + simple: "# script.py" method: simple: GET saveAsFile: simple: "yes" url: - simple: http://www.pdf995.com/samples/pdf.pdf + simple: https://raw.githubusercontent.com/demisto/content/3ef746414beb35924fd5ce4c74bf646867ccbba6/Packs/CrowdStrikeFalconX/Integrations/CrowdStrikeFalconX/CrowdStrikeFalconX.py separatecontext: false view: |- { From c04374f23b8e48b1ce4a0dd621c4a2e8a5962d00 Mon Sep 17 00:00:00 2001 From: Yuval Hayun <70104171+YuvHayun@users.noreply.github.com> Date: Wed, 28 Feb 2024 11:47:21 +0200 Subject: [PATCH 101/272] Raise neo4j memory limit. (#33120) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3ebbf3c1e5d5..89d7e99d12fd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -106,7 +106,7 @@ references: neo4j_conf_file="/etc/neo4j/neo4j.conf" sudo echo "dbms.security.procedures.unrestricted=apoc.*" >> $neo4j_conf_file sudo echo "dbms.security.procedures.allowlist=apoc.*" >> $neo4j_conf_file - sudo echo "dbms.memory.transaction.total.max=600m" >> $neo4j_conf_file + sudo echo "dbms.memory.transaction.total.max=2000m" >> $neo4j_conf_file apoc_conf_file="/etc/neo4j/apoc.conf" sudo echo "apoc.export.file.enabled=true" > $apoc_conf_file From d61a8fea4ac01180f306d33ae67c85a49331cbf7 Mon Sep 17 00:00:00 2001 From: Judah Schwartz Date: Wed, 28 Feb 2024 12:39:08 +0200 Subject: [PATCH 102/272] Deprecate old bmc (#33118) * deprecate * deprecated integration * fix description * fixed rn --- .../Remedy-On-Demand/Integrations/RemedyOnDemand/README.md | 2 +- .../Integrations/RemedyOnDemand/RemedyOnDemand.yml | 5 +++-- Packs/Remedy-On-Demand/ReleaseNotes/1_1_4.md | 6 ++++++ Packs/Remedy-On-Demand/pack_metadata.json | 6 +++--- 4 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 Packs/Remedy-On-Demand/ReleaseNotes/1_1_4.md diff --git a/Packs/Remedy-On-Demand/Integrations/RemedyOnDemand/README.md b/Packs/Remedy-On-Demand/Integrations/RemedyOnDemand/README.md index b9628bd4a5e1..652702615b23 100644 --- a/Packs/Remedy-On-Demand/Integrations/RemedyOnDemand/README.md +++ b/Packs/Remedy-On-Demand/Integrations/RemedyOnDemand/README.md @@ -1,4 +1,4 @@ -Use Remedy On-Demand to manage tickets +Deprecated. use BMC Helix ITSM instead. This integration was integrated and tested with version 9.1 of Remedy On-Demand ## Configure Remedy On-Demand on Cortex XSOAR diff --git a/Packs/Remedy-On-Demand/Integrations/RemedyOnDemand/RemedyOnDemand.yml b/Packs/Remedy-On-Demand/Integrations/RemedyOnDemand/RemedyOnDemand.yml index 9ea3d1be5fec..eb97608d5aba 100644 --- a/Packs/Remedy-On-Demand/Integrations/RemedyOnDemand/RemedyOnDemand.yml +++ b/Packs/Remedy-On-Demand/Integrations/RemedyOnDemand/RemedyOnDemand.yml @@ -2,9 +2,10 @@ commonfields: id: Remedy On-Demand version: -1 name: Remedy On-Demand -display: Remedy On-Demand +display: Remedy On-Demand (Deprecated) +deprecated: true category: Case Management -description: Use Remedy On-Demand to manage tickets +description: Deprecated. Use BMC Helix ITSM instead. configuration: - display: Server URL (e.g. 'https://myurl.com', 'http://41.79.151.82') name: url diff --git a/Packs/Remedy-On-Demand/ReleaseNotes/1_1_4.md b/Packs/Remedy-On-Demand/ReleaseNotes/1_1_4.md new file mode 100644 index 000000000000..c00cb08fe4bf --- /dev/null +++ b/Packs/Remedy-On-Demand/ReleaseNotes/1_1_4.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Remedy On-Demand (Deprecated) + +- Deprecated. Use *BMC Helix ITSM* instead. diff --git a/Packs/Remedy-On-Demand/pack_metadata.json b/Packs/Remedy-On-Demand/pack_metadata.json index aa9eb7d82e74..829a0807a756 100644 --- a/Packs/Remedy-On-Demand/pack_metadata.json +++ b/Packs/Remedy-On-Demand/pack_metadata.json @@ -1,8 +1,8 @@ { - "name": "BMC Remedy On-Demand", - "description": "Use Remedy On-Demand to manage tickets", + "name": "BMC Remedy On-Demand (Deprecated)", + "description": "Deprecated. Use BMC Helix ITSM instead", "support": "xsoar", - "currentVersion": "1.1.3", + "currentVersion": "1.1.4", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From ecfbdda443d6d054e265a91effae7326fbee3519 Mon Sep 17 00:00:00 2001 From: Moshe Eichler <78307768+MosheEichler@users.noreply.github.com> Date: Wed, 28 Feb 2024 12:39:26 +0200 Subject: [PATCH 103/272] Fix/[XSUP-33100]/GitHub/Payload too large (#33045) * CR change user agent and remove data in get request * add ut * add ut * revert * RN * revert * RN --- Packs/GitHub/Integrations/GitHub/GitHub.py | 2 +- Packs/GitHub/Integrations/GitHub/GitHub.yml | 2 +- .../GitHub/Integrations/GitHub/GitHub_test.py | 45 ++++++++++++++++++- Packs/GitHub/ReleaseNotes/2_0_29.md | 7 +++ Packs/GitHub/pack_metadata.json | 2 +- 5 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 Packs/GitHub/ReleaseNotes/2_0_29.md diff --git a/Packs/GitHub/Integrations/GitHub/GitHub.py b/Packs/GitHub/Integrations/GitHub/GitHub.py index 4d3f8a74ca0e..cd16a20d64bf 100644 --- a/Packs/GitHub/Integrations/GitHub/GitHub.py +++ b/Packs/GitHub/Integrations/GitHub/GitHub.py @@ -115,7 +115,7 @@ def http_request(method, url_suffix, params=None, data=None, headers=None, is_ra BASE_URL + url_suffix, verify=USE_SSL, params=params, - data=json.dumps(data), + data=json.dumps(data) if data else None, headers=headers or HEADERS ) if res.status_code >= 400: diff --git a/Packs/GitHub/Integrations/GitHub/GitHub.yml b/Packs/GitHub/Integrations/GitHub/GitHub.yml index 85f8854e7e97..edff1380a3f8 100644 --- a/Packs/GitHub/Integrations/GitHub/GitHub.yml +++ b/Packs/GitHub/Integrations/GitHub/GitHub.yml @@ -3662,7 +3662,7 @@ script: - contextPath: GitHub.Workflow.updated_at description: Datetime the GitHub workflow was updated at. type: Date - dockerimage: demisto/auth-utils:1.0.0.76157 + dockerimage: demisto/auth-utils:1.0.0.88424 isfetch: true runonce: false script: '-' diff --git a/Packs/GitHub/Integrations/GitHub/GitHub_test.py b/Packs/GitHub/Integrations/GitHub/GitHub_test.py index f7d01abfd814..e5463d07a25f 100644 --- a/Packs/GitHub/Integrations/GitHub/GitHub_test.py +++ b/Packs/GitHub/Integrations/GitHub/GitHub_test.py @@ -7,7 +7,7 @@ from CommonServerPython import CommandResults from GitHub import main, list_branch_pull_requests, list_all_projects_command, \ add_issue_to_project_board_command, get_path_data, github_releases_list_command, get_branch_command, \ - list_issue_comments + list_issue_comments, http_request import GitHub REGULAR_BASE_URL = 'https://api.github.com' @@ -504,3 +504,46 @@ def test_github_list_workflow(mocker): mocker_results.assert_called_once() assert mocker_results.call_args[0][0].outputs[0]['head_branch'] == 'master' + + +def test_http_request(): + """ + Given: + - A body of a post request + When: + - Calling the 'http_request' function + Then: + - Ensure the correctness of the request body. + """ + + GitHub.BASE_URL = REGULAR_BASE_URL + GitHub.USE_SSL = '' + GitHub.HEADERS = {} + + # Test HTTP request with data equal to 'dictionary' + with requests_mock.Mocker() as m: + mock_req = m.post(f'{REGULAR_BASE_URL}/test', json={}) + response = http_request('POST', '/test', data={'test_key': 'test_value'}) + assert response == {} + assert mock_req.last_request.text == '{"test_key": "test_value"}' + + # Test HTTP request with data equal to empty 'dictionary' + with requests_mock.Mocker() as m: + mock_req = m.post(f'{REGULAR_BASE_URL}/test', json={}) + response = http_request('POST', '/test', data={}) + assert response == {} + assert not mock_req.last_request.text + + # Test HTTP request with data equal to 'null' + with requests_mock.Mocker() as m: + mock_req = m.post(f'{REGULAR_BASE_URL}/test', json={}) + response = http_request('POST', '/test', data='null') + assert response == {} + assert mock_req.last_request.text == '"null"' + + # Test HTTP request with data equal to 'None' + with requests_mock.Mocker() as m: + mock_req = m.post(f'{REGULAR_BASE_URL}/test', json={}) + response = http_request('POST', '/test', data=None) + assert response == {} + assert not mock_req.last_request.text diff --git a/Packs/GitHub/ReleaseNotes/2_0_29.md b/Packs/GitHub/ReleaseNotes/2_0_29.md new file mode 100644 index 000000000000..b2dd28ae473f --- /dev/null +++ b/Packs/GitHub/ReleaseNotes/2_0_29.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### GitHub + +- Updated the Docker image to: *demisto/auth-utils:1.0.0.88424*. +- Fixed an issue where some commands failed on http requests with the get method. diff --git a/Packs/GitHub/pack_metadata.json b/Packs/GitHub/pack_metadata.json index e207af58630f..2bc01545c4f6 100644 --- a/Packs/GitHub/pack_metadata.json +++ b/Packs/GitHub/pack_metadata.json @@ -2,7 +2,7 @@ "name": "GitHub", "description": "Manage GitHub issues and pull requests directly from Cortex XSOAR", "support": "xsoar", - "currentVersion": "2.0.28", + "currentVersion": "2.0.29", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 716e44f76198cbfb6a0b9f22468c433df02a5bc1 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Wed, 28 Feb 2024 15:51:09 +0200 Subject: [PATCH 104/272] [Marketplace Contribution] Cisco Umbrella cloud security - Content Pack Update (#33070) * [Marketplace Contribution] Cisco Umbrella cloud security - Content Pack Update (#32939) * "contribution update to pack "Cisco Umbrella cloud security"" * Revert description * remove try/except around get_access_token call * removed resp_type and ok_codes arguments passed to _http_request * currentVersion to 2.0.8 Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> * Update Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_1_0.md Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> * Rename 2_1_0.md to 2_0_8.md * add test_get_access_token * Create token.json * Apply suggestions from code review Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> * provide access_token dict and update docstrings test_get_access_token() - token.json deleted, so provided response dict containing access_token within function updated "When" docstrings of all test functions * revert * Delete Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/test_data/token.json * update currentVersion to 2.0.9 * Create 2_0_9.md --------- Co-authored-by: Randy Baldwin <32545292+randomizerxd@users.noreply.github.com> Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> * fixed lint errors --------- Co-authored-by: xsoar-bot <67315154+xsoar-bot@users.noreply.github.com> Co-authored-by: Randy Baldwin <32545292+randomizerxd@users.noreply.github.com> Co-authored-by: merit-maita <49760643+merit-maita@users.noreply.github.com> Co-authored-by: merit-maita --- .../CiscoUmbrellaCloudSecurityv2.py | 47 ++++++++++++++----- .../CiscoUmbrellaCloudSecurityv2.yml | 33 ------------- .../CiscoUmbrellaCloudSecurityv2_test.py | 41 ++++++++++++---- .../ReleaseNotes/2_0_9.md | 6 +++ .../pack_metadata.json | 4 +- 5 files changed, 76 insertions(+), 55 deletions(-) create mode 100644 Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_0_9.md diff --git a/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.py b/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.py index 9abc59ddb2eb..8eae698d72b9 100644 --- a/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.py +++ b/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.py @@ -1,10 +1,11 @@ +import demistomock as demisto # noqa: F401 +from CommonServerPython import * # noqa: F401 + import enum import http from collections.abc import Callable from typing import Any, TypeVar -import demistomock as demisto # noqa: F401 -from CommonServerPython import * # noqa: F401 BASE_URL = 'https://api.umbrella.com' @@ -83,17 +84,39 @@ def login(self) -> None: Log in to the API using the API key and API secret. The access token is stored in the headers of the request. """ - response = self._http_request( - method='POST', - url_suffix=Client.AUTH_SUFFIX, - auth=(self.api_key, self.api_secret), - ) + access_token = self.get_access_token() + self._headers['Authorization'] = f'Bearer {access_token}' - try: - access_token = response['access_token'] - self._headers['Authorization'] = f'Bearer {access_token}' - except Exception as e: - raise DemistoException(f'Failed logging in: {response}') from e + def get_access_token(self): + """ + Get an access token that was previously created if it is still valid, else, generate a new access token from + the API key and secret. + """ + # Check if there is an existing valid access token + integration_context = get_integration_context() + if integration_context.get('access_token') and integration_context.get('expiry_time') > date_to_timestamp(datetime.now()): + return integration_context.get('access_token') + else: + try: + res = self._http_request( + method='POST', + url_suffix=Client.AUTH_SUFFIX, + headers={'Content-Type': 'application/x-www-form-urlencoded'}, + auth=(self.api_key, self.api_secret), + data={'grant_type': 'client_credentials'} + ) + if res.get('access_token'): + expiry_time = date_to_timestamp(datetime.now(), date_format='%Y-%m-%dT%H:%M:%S') + expiry_time += res.get('expires_in', 0) * 1000 - 10 + context = { + 'access_token': res.get('access_token'), + 'expiry_time': expiry_time + } + set_integration_context(context) + return res.get('access_token') + except Exception as e: + return_error(f'Error occurred while creating an access token. Please check the instance configuration.' + f'\n\n{e.args[0]}') def _get_destination_payload( self, diff --git a/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.yml b/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.yml index 77601f3559c7..41c154ea74ad 100644 --- a/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.yml +++ b/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2.yml @@ -29,27 +29,18 @@ script: - name: destination_list_id description: The ID of the destination list. Destination lists can be fetched with the `umbrella-destination-lists-list` command. required: true - isArray: false - name: destination_ids description: Comma-separated list of destination IDs to be retrieved from a list of destinations. - required: false isArray: true - name: destinations description: Comma-separated list of destinations to retrieve, a destination may be a domain, URL, or IP address. - required: false isArray: true - name: page description: Page number of paginated results. Minimum 1; Default 1. - required: false - isArray: false - name: page_size description: The number of items per page. Minimum 1; Maximum 100; Default 50. - required: false - isArray: false - name: limit description: The number of items per page. Minimum 1. - required: false - isArray: false defaultValue: '50' outputs: - type: String @@ -73,15 +64,11 @@ script: - name: destination_list_id description: The ID of the destination list. Destination lists can be fetched with the `umbrella-destination-lists-list` command. required: true - isArray: false - name: destinations description: Comma-separated list of destinations. A destination may be a URL, IPv4, CIDR or fully qualified domain name. required: true - isArray: false - name: comment description: A comment about all the inserted destinations. - required: false - isArray: false defaultValue: Added from XSOAR outputs: - type: Number @@ -126,7 +113,6 @@ script: - name: destination_list_id description: The ID of the destination list. Destination lists can be fetched with the `umbrella-destination-lists-list` command. required: true - isArray: false - name: destination_ids description: Comma-separated list of destination IDs. Destinations can be fetched with the `umbrella-destination-list` command. required: true @@ -173,20 +159,12 @@ script: arguments: - name: destination_list_id description: The ID of the destination list to retrieve. - required: false - isArray: false - name: page description: Page number of paginated results. Minimum 1; Default 1. - required: false - isArray: false - name: page_size description: The number of items per page. Minimum 1; Maximum 100; Default 50. - required: false - isArray: false - name: limit description: The maximum number of records to retrieve. Minimum 1. - required: false - isArray: false defaultValue: '50' outputs: - type: Number @@ -242,8 +220,6 @@ script: arguments: - name: bundle_type description: The type of the Umbrella policy associated with the destination list. If the field is not specified, the default value is 'DNS'. - required: false - isArray: false auto: PREDEFINED predefined: - 'DNS' @@ -251,7 +227,6 @@ script: - name: access description: 'The type of access for the destination list. Valid values are "allow" or "block". Accepted types for destination list with the access "allow" are: DOMAIN, IPv4 and CIDR. Accepted types for destination list with the access "block" are: URL and DOMAIN.' required: true - isArray: false auto: PREDEFINED predefined: - 'allow' @@ -259,7 +234,6 @@ script: - name: is_global description: Specifies whether the destination list is a global destination list. There is only one default destination list of type 'allow' or 'block' for an organization. required: true - isArray: false auto: PREDEFINED predefined: - 'True' @@ -267,15 +241,11 @@ script: - name: name description: The name of the destination list. required: true - isArray: false - name: destinations description: Comma-separated list of destinations. A destination may be a URL, IPv4, CIDR or fully qualified domain name. - required: false isArray: true - name: destinations_comment description: A comment about all the inserted destinations. - required: false - isArray: false defaultValue: Added from XSOAR outputs: - type: Number @@ -320,11 +290,9 @@ script: - name: destination_list_id description: The ID of the destination list. Destination lists can be fetched with the `umbrella-destination-lists-list` command. required: true - isArray: false - name: name description: The name of the destination list. required: true - isArray: false outputs: - type: Number contextPath: Umbrella.DestinationLists.id @@ -368,7 +336,6 @@ script: - name: destination_list_id description: The ID of the destination list. Destination lists can be fetched with the `umbrella-destination-lists-list` command. required: true - isArray: false - arguments: - description: Organization ID. name: orgId diff --git a/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2_test.py b/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2_test.py index fb8439a00df7..1e8bce64ee26 100644 --- a/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2_test.py +++ b/Packs/Cisco-umbrella-cloud-security/Integrations/CiscoUmbrellaCloudSecurityv2/CiscoUmbrellaCloudSecurityv2_test.py @@ -59,7 +59,7 @@ def test_list_destinations_command(requests_mock, mock_client): - A destination list ID When: - - list_destinations_command + - Running the umbrella-destinations-list command. Then: - Ensure that the CommandResults outputs_prefix is correct. @@ -111,7 +111,7 @@ def test_list_destinations_command_fetch_destinations(requests_mock, mock_client - A destination list ID When: - - list_destinations_command + - Running the umbrella-destinations-list command. Then: - Ensure that the CommandResults outputs_prefix is correct. @@ -168,7 +168,7 @@ def test_add_destinations_command(requests_mock, mock_client): - A destination list ID and destinations When: - - add_destinations_command + - Running the umbrella-destination-add command. Then: - Ensure that the CommandResults raw_response is correct. @@ -206,7 +206,7 @@ def test_delete_destination_command(requests_mock, mock_client): - A destination list ID and destination IDs When: - - delete_destination_command + - Running the umbrella-destination-delete command. Then: - Ensure that the CommandResults readable_output is correct. @@ -243,7 +243,7 @@ def test_list_destination_lists_command(requests_mock, mock_client): - A destination list ID When: - - list_destination_lists_command + - Running the umbrella-destination-lists-list command. Then: - Ensure that the CommandResults outputs_prefix is correct. @@ -280,7 +280,7 @@ def test_list_destination_lists_command_list_request(requests_mock, mock_client) - Nothing When: - - list_destination_lists_command + - Running the umbrella-destination-lists-list command. Then: - Ensure that the CommandResults outputs_prefix is correct. @@ -314,7 +314,7 @@ def test_create_destination_list_command(requests_mock, mock_client): for a new destination list When: - - create_destination_list_command + - Running the umbrella-destination-list-create command. Then: - Ensure that the CommandResults outputs_prefix is correct. @@ -356,7 +356,7 @@ def test_update_destination_list_command(requests_mock, mock_client): - A destination list ID and a new name When: - - update_destination_list_command + - Running the umbrella-destination-list-update command. Then: - Ensure that the CommandResults outputs_prefix is correct. @@ -418,3 +418,28 @@ def test_delete_destination_list_command(requests_mock, mock_client): assert command_results.readable_output == expected_readable_output assert command_results.raw_response == response + + +def test_get_access_token(requests_mock, mock_client): + """ + Scenario: + - Test the flow of getting an access token + When: + - Running the get_access_token method. + Then: + - Ensure that an access token is returned. + """ + + response = { + "token_type": "bearer", + "access_token": "Pichu", + "expires_in": 3600 + } + requests_mock.post( + url=f'{CiscoUmbrellaCloudSecurityv2.BASE_URL}/auth/v2/token', + json=response + ) + + access_token = CiscoUmbrellaCloudSecurityv2.Client.get_access_token(mock_client) + + assert access_token == response.get('access_token') diff --git a/Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_0_9.md b/Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_0_9.md new file mode 100644 index 000000000000..d43362467191 --- /dev/null +++ b/Packs/Cisco-umbrella-cloud-security/ReleaseNotes/2_0_9.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Cisco Umbrella Cloud Security v2 + +- Improved implementation of retrieving the *Access Token* in the authentication process. diff --git a/Packs/Cisco-umbrella-cloud-security/pack_metadata.json b/Packs/Cisco-umbrella-cloud-security/pack_metadata.json index 26375fc39992..ed744f5f0bb9 100644 --- a/Packs/Cisco-umbrella-cloud-security/pack_metadata.json +++ b/Packs/Cisco-umbrella-cloud-security/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cisco Umbrella cloud security", "description": "Basic integration with Cisco Umbrella that allows you to add domains to destination lists (e.g. global block / allow)", "support": "xsoar", - "currentVersion": "2.0.8", + "currentVersion": "2.0.9", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", @@ -18,4 +18,4 @@ "marketplacev2" ], "certification": "certified" -} \ No newline at end of file +} From 0a8742f6c87dda583aa6d589defa385f8a41664e Mon Sep 17 00:00:00 2001 From: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:06:59 +0200 Subject: [PATCH 105/272] [EDL] get_indicators_to_format - fix demisto.error (#33123) * update demisto.error * update demisto.error * pre-commit --- Packs/EDL/Integrations/EDL/EDL.py | 4 +++- Packs/EDL/Integrations/EDL/EDL.yml | 2 +- Packs/EDL/Integrations/EDL/EDL_test.py | 18 +++++++++--------- Packs/EDL/ReleaseNotes/3_2_20.md | 7 +++++++ Packs/EDL/pack_metadata.json | 2 +- 5 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 Packs/EDL/ReleaseNotes/3_2_20.md diff --git a/Packs/EDL/Integrations/EDL/EDL.py b/Packs/EDL/Integrations/EDL/EDL.py index cb9a2e5f9bd4..964639cf99b2 100644 --- a/Packs/EDL/Integrations/EDL/EDL.py +++ b/Packs/EDL/Integrations/EDL/EDL.py @@ -350,6 +350,8 @@ def get_indicators_to_format(indicator_searcher: IndicatorsSearcher, for ioc_res in indicator_searcher: fetched_iocs = ioc_res.get('iocs') or [] for ioc in fetched_iocs: + demisto.debug(f"Parsing the following indicator: {ioc.get('value')}") + ioc_counter += 1 if request_args.out_format == FORMAT_PROXYSG: files_by_category = create_proxysg_out_format(ioc, files_by_category, request_args) @@ -374,7 +376,7 @@ def get_indicators_to_format(indicator_searcher: IndicatorsSearcher, break except Exception as e: - demisto.error(f'Error parsing the following indicator: {ioc.get("value")}\n{e}') + demisto.error(f'Error in parsing the indicators, error: {str(e)}') # 429 error can only be raised when the Elasticsearch instance encountered an error if '[429] Failed with error' in str(e): version = demisto.demistoVersion() diff --git a/Packs/EDL/Integrations/EDL/EDL.yml b/Packs/EDL/Integrations/EDL/EDL.yml index 63ed6b752362..cad0b88073dc 100644 --- a/Packs/EDL/Integrations/EDL/EDL.yml +++ b/Packs/EDL/Integrations/EDL/EDL.yml @@ -432,7 +432,7 @@ script: - 'False' - 'True' description: Updates values stored in the List (only available On-Demand). - dockerimage: demisto/flask-nginx:1.0.0.85991 + dockerimage: demisto/flask-nginx:1.0.0.87872 longRunning: true longRunningPort: true script: '-' diff --git a/Packs/EDL/Integrations/EDL/EDL_test.py b/Packs/EDL/Integrations/EDL/EDL_test.py index 6b48a803b65d..ae87bd1e8a0a 100644 --- a/Packs/EDL/Integrations/EDL/EDL_test.py +++ b/Packs/EDL/Integrations/EDL/EDL_test.py @@ -102,11 +102,11 @@ def test_get_edl_on_demand__with_cache(self, mocker): mocker.patch.object(edl, 'get_integration_context', return_value={}) actual_edl, original_indicators_count = edl.get_edl_on_demand() - with open(edl.EDL_ON_DEMAND_CACHE_PATH, 'r') as f: + with open(edl.EDL_ON_DEMAND_CACHE_PATH) as f: expected_edl = f.read() assert actual_edl == expected_edl - assert edl.EDL_ON_DEMAND_CACHE_ORIGINAL_SIZE == original_indicators_count + assert original_indicators_count == edl.EDL_ON_DEMAND_CACHE_ORIGINAL_SIZE def test_get_edl_on_demand__with_refresh_signal(self, mocker): """ @@ -127,7 +127,7 @@ def test_get_edl_on_demand__with_refresh_signal(self, mocker): mocker.patch.object(edl, 'create_new_edl', return_value=(expected_edl, 1)) actual_edl, _ = edl.get_edl_on_demand() - with open(edl.EDL_ON_DEMAND_CACHE_PATH, 'r') as f: + with open(edl.EDL_ON_DEMAND_CACHE_PATH) as f: cached_edl = f.read() assert actual_edl == expected_edl == cached_edl @@ -228,7 +228,7 @@ def test_create_new_edl_edge_cases(self, mocker, requests_mock): {"value": "*.co.uk", "indicator_type": "Domain"}, # tld {"value": "*.google.com", "indicator_type": "Domain"}, # no tld {"value": "aא.com", "indicator_type": "URL"}] # no ascii - f = '\n'.join((json.dumps(indicator) for indicator in indicators)) + f = '\n'.join(json.dumps(indicator) for indicator in indicators) request_args = edl.RequestArguments(collapse_ips=DONT_COLLAPSE, maximum_cidr_size=2) mocker.patch.object(edl, 'get_indicators_to_format', return_value=(io.StringIO(f), 6)) edl_v, _ = edl.create_new_edl(request_args) @@ -272,7 +272,7 @@ def test_create_new_edl_with_offset(self, mocker, requests_mock): {"value": "*.co.uk", "indicator_type": "Domain"}, # tld {"value": "*.google.com", "indicator_type": "Domain"}, # no tld {"value": "aא.com", "indicator_type": "URL"}] # no ascii - f = '\n'.join((json.dumps(indicator) for indicator in indicators)) + f = '\n'.join(json.dumps(indicator) for indicator in indicators) # create_new_edl with no offset request_args = edl.RequestArguments(collapse_ips=DONT_COLLAPSE, maximum_cidr_size=8) @@ -299,7 +299,7 @@ def test_create_json_out_format(self): """ from EDL import create_json_out_format, RequestArguments returned_output = [] - with open('test_data/demisto_url_iocs.json', 'r') as iocs_json_f: + with open('test_data/demisto_url_iocs.json') as iocs_json_f: iocs_json = json.loads(iocs_json_f.read()) # strips port numbers @@ -328,7 +328,7 @@ def test_create_csv_out_format(self): - assert the result """ from EDL import create_csv_out_format, RequestArguments - with open('test_data/demisto_url_iocs.json', 'r') as iocs_json_f: + with open('test_data/demisto_url_iocs.json') as iocs_json_f: iocs_json = json.loads(iocs_json_f.read()) request_args = RequestArguments(query='', drop_invalids=True, url_port_stripping=True, url_protocol_stripping=True) @@ -353,7 +353,7 @@ def test_create_mwg_out_format(self): - assert the result """ from EDL import create_mwg_out_format, RequestArguments - with open('test_data/demisto_url_iocs.json', 'r') as iocs_json_f: + with open('test_data/demisto_url_iocs.json') as iocs_json_f: iocs_json = json.loads(iocs_json_f.read()) request_args = RequestArguments(query='', drop_invalids=True, url_port_stripping=True, url_protocol_stripping=True) @@ -381,7 +381,7 @@ def test_create_proxysg_out_format(self): """ from EDL import create_proxysg_out_format, RequestArguments, create_proxysg_all_category_out_format files_by_category = {} - with open('test_data/demisto_url_iocs.json', 'r') as iocs_json_f: + with open('test_data/demisto_url_iocs.json') as iocs_json_f: iocs_json = json.loads(iocs_json_f.read()) request_args = RequestArguments(query='', drop_invalids=True, url_port_stripping=True, diff --git a/Packs/EDL/ReleaseNotes/3_2_20.md b/Packs/EDL/ReleaseNotes/3_2_20.md new file mode 100644 index 000000000000..23bdcafb4934 --- /dev/null +++ b/Packs/EDL/ReleaseNotes/3_2_20.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Generic Export Indicators Service + +- Improved error handling in the *get_indicators_to_format* function for cases where IOC values are not always defined. +- Updated the Docker image to: *demisto/flask-nginx:1.0.0.87872*. \ No newline at end of file diff --git a/Packs/EDL/pack_metadata.json b/Packs/EDL/pack_metadata.json index 1960f83d90bb..6c644f960b2f 100644 --- a/Packs/EDL/pack_metadata.json +++ b/Packs/EDL/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Generic Export Indicators Service", "description": "Use this pack to generate a list based on your Threat Intel Library, and export it to ANY other product in your network, such as your firewall, agent or SIEM. This pack is built for ongoing distribution of indicators from XSOAR to other products in the network, by creating an endpoint with a list of indicators that can be pulled by external vendors.", "support": "xsoar", - "currentVersion": "3.2.19", + "currentVersion": "3.2.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From fbb1d57b376ce9dc8b3c4a648d00ba58663e63dd Mon Sep 17 00:00:00 2001 From: anas-yousef <44998563+anas-yousef@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:41:43 +0200 Subject: [PATCH 106/272] Splunkpy cache incidents by window (#32857) * Added solution * Added Rns * Updated docker image * Added docstrings * Bump pack from version SplunkPy to 3.1.20. * Added logs and comments --------- Co-authored-by: Content Bot --- .../Integrations/SplunkPy/SplunkPy.py | 57 +++++++++----- .../Integrations/SplunkPy/SplunkPy.yml | 2 +- .../Integrations/SplunkPy/SplunkPy_test.py | 77 +++++++++++++++++++ Packs/SplunkPy/ReleaseNotes/3_1_20.md | 7 ++ Packs/SplunkPy/pack_metadata.json | 2 +- 5 files changed, 124 insertions(+), 21 deletions(-) create mode 100644 Packs/SplunkPy/ReleaseNotes/3_1_20.md diff --git a/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy.py b/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy.py index 00447dcbc067..9038fbc9e2ab 100644 --- a/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy.py +++ b/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy.py @@ -230,26 +230,44 @@ def extensive_log(message): demisto.debug(message) -def remove_old_incident_ids(last_run_fetched_ids, current_epoch_time, occurred_look_behind): - """Remove all the IDs of all the incidents that were found more than twice the look behind time frame, - to stop our IDs dict from becoming too large. +def remove_irrelevant_incident_ids(last_run_fetched_ids: dict[str, dict[str, str]], window_start_time: str, + window_end_time: str) -> dict[str, Any]: + """Remove all the IDs of the fetched incidents that are no longer in the fetch window, to prevent our + last run object from becoming too large. Args: - last_run_fetched_ids (list): All the event IDs that weren't out of date in the last run + all the new event IDs - from newly fetched events in this run. - current_epoch_time (int): The current time in epoch. - occurred_look_behind (int): The max look behind time (parameter, as defined by the user). + last_run_fetched_ids (dict[str, tuple]): The IDs incidents that were fetched in previous fetches. + window_start_time (str): The window start time. + window_end_time (str): The window end time. Returns: - new_last_run_fetched_ids (list): The updated list of IDs, without old IDs. + dict[str, Any]: The updated list of IDs, without irrelevant IDs. """ - new_last_run_fetched_ids = {} - for inc_id, addition_time in list(last_run_fetched_ids.items()): - max_look_behind_in_seconds = occurred_look_behind * 60 - deletion_threshold_in_seconds = max_look_behind_in_seconds * 2 - if current_epoch_time - addition_time < deletion_threshold_in_seconds: - new_last_run_fetched_ids[inc_id] = addition_time - + new_last_run_fetched_ids: dict[str, dict[str, str]] = {} + window_start_datetime = datetime.strptime(window_start_time, SPLUNK_TIME_FORMAT) + demisto.debug(f'Beginning to filter irrelevant IDs with respect to window {window_start_time} - {window_end_time}') + for incident_id, incident_occurred_time in last_run_fetched_ids.items(): + # We divided the handling of the last fetched IDs since we changed the handling of them + # The first implementation caused IDs to be removed from the cache, even though they were still relevant + # The second implementation now only removes the cached IDs that are not relevant to the fetch window + extensive_log(f'[SplunkPy] Checking if {incident_id} is relevant to fetch window') + if isinstance(incident_occurred_time, dict): + # To handle last fetched IDs + # Last fetched IDs hold the occurred time that they were seen, and will be deleted from + # the last fetched IDs once they pass the fetch window + incident_start_datetime = datetime.strptime(incident_occurred_time.get('occurred_time', ''), SPLUNK_TIME_FORMAT) + if incident_start_datetime >= window_start_datetime: + # We keep the incident, since it is still in the fetch window + extensive_log(f'[SplunkPy] Keeping {incident_id} as part of the last fetched IDs. {incident_start_datetime=}') + new_last_run_fetched_ids[incident_id] = incident_occurred_time + else: + extensive_log(f'[SplunkPy] Removing {incident_id} from the last fetched IDs') + else: + # To handle last fetched IDs before version 3_1_20 + # Last fetched IDs held the epoch time of their appearance, they will now hold the + # new format, with an occurred time equal to the end of the window + extensive_log(f'[SplunkPy] {incident_id} was saved using old implementation, keeping') + new_last_run_fetched_ids[incident_id] = {'occurred_time': window_end_time} return new_last_run_fetched_ids @@ -349,7 +367,7 @@ def fetch_notables(service: client.Service, mapper: UserMappingObject, comment_t latest_time = last_run_latest_time or now kwargs_oneshot = build_fetch_kwargs(params, occured_start_time, latest_time, search_offset) fetch_query = build_fetch_query(params) - last_run_fetched_ids = last_run_data.get('found_incidents_ids', {}) + last_run_fetched_ids: dict[str, Any] = last_run_data.get('found_incidents_ids', {}) if late_indexed_pagination := last_run_data.get('late_indexed_pagination'): # This is for handling the case when events get indexed late, and inserted in pages # that we have already went through @@ -389,12 +407,13 @@ def fetch_notables(service: client.Service, mapper: UserMappingObject, comment_t num_of_dropped += 1 extensive_log(f'[SplunkPy] - Dropped incident {incident_id} due to duplication.') - current_epoch_time = int(time.time()) extensive_log(f'[SplunkPy] Size of last_run_fetched_ids before adding new IDs: {len(last_run_fetched_ids)}') for incident_id in incident_ids_to_add: - last_run_fetched_ids[incident_id] = current_epoch_time + last_run_fetched_ids[incident_id] = {'occurred_time': occured_start_time} extensive_log(f'[SplunkPy] Size of last_run_fetched_ids after adding new IDs: {len(last_run_fetched_ids)}') - last_run_fetched_ids = remove_old_incident_ids(last_run_fetched_ids, current_epoch_time, occurred_look_behind) + + # New way to remove IDs + last_run_fetched_ids = remove_irrelevant_incident_ids(last_run_fetched_ids, occured_start_time, latest_time) extensive_log('[SplunkPy] Size of last_run_fetched_ids after ' f'removing old IDs: {len(last_run_fetched_ids)}') extensive_log(f'[SplunkPy] SplunkPy - incidents fetched on last run = {last_run_fetched_ids}') diff --git a/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy.yml b/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy.yml index 53b43b6f0f6a..cef03dcf81c3 100644 --- a/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy.yml +++ b/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy.yml @@ -666,7 +666,7 @@ script: - contextPath: Splunk.UserMapping.SplunkUser description: Splunk user mapping. type: String - dockerimage: demisto/splunksdk-py3:1.0.0.86438 + dockerimage: demisto/splunksdk-py3:1.0.0.87498 isfetch: true ismappable: true isremotesyncin: true diff --git a/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy_test.py b/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy_test.py index 33c15a527dfd..f0691db78688 100644 --- a/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy_test.py +++ b/Packs/SplunkPy/Integrations/SplunkPy/SplunkPy_test.py @@ -574,6 +574,83 @@ def __init__(self): assert output == expected_output +class TestFetchRemovingIrrelevantIncidents: + + notable1 = {'status': '5', 'event_id': '3'} + notable2 = {'status': '6', 'event_id': '4'} + + # In order to mock the service.jobs.oneshot() call in the fetch_notables function, we need to create + # the following two classes + class Jobs: + def __init__(self): + self.oneshot = lambda x, **kwargs: TestFetchForLateIndexedEvents.notable1 + + class Service: + def __init__(self): + self.jobs = TestFetchForLateIndexedEvents.Jobs() + + def test_backwards_compatible(self, mocker: MockerFixture): + """ + Given + - Incident IDs that were fetched in the last fetch round with the epoch time of their occurrence + + When + - Fetching notables + + Then + - Make sure that the last fetched IDs now hold the start of the fetch window, and not the epoch time + """ + from SplunkPy import UserMappingObject + + mocker.patch.object(demisto, 'setLastRun') + mock_last_run = {'time': '2024-02-12T10:00:00', 'latest_time': '2024-02-19T10:00:00', + 'found_incidents_ids': {'1': 1700497516}} + mock_params = {'fetchQuery': '`notable` is cool', 'fetch_limit': 2} + mocker.patch('demistomock.getLastRun', return_value=mock_last_run) + mocker.patch('demistomock.params', return_value=mock_params) + mocker.patch('splunklib.results.JSONResultsReader', return_value=[self.notable1, + self.notable2]) + service = self.Service() + set_last_run_mocker = mocker.patch('demistomock.setLastRun') + mapper = UserMappingObject(service, False) + splunk.fetch_incidents(service, mapper, 'from_xsoar', 'from_splunk') + last_fetched_ids = set_last_run_mocker.call_args_list[0][0][0]['found_incidents_ids'] + assert last_fetched_ids == {'1': {'occurred_time': '2024-02-19T10:00:00'}, + '3': {'occurred_time': '2024-02-12T10:00:00'}, + '4': {'occurred_time': '2024-02-12T10:00:00'}} + + def test_remove_irrelevant_fetched_incident_ids(self, mocker: MockerFixture): + """ + Given + - Incident IDs that were fetched in the last fetch round + + When + - Fetching notables + + Then + - Make sure that the fetched IDs that are no longer in the fetch window are removed + """ + from SplunkPy import UserMappingObject + + mocker.patch.object(demisto, 'setLastRun') + mock_last_run = {'time': '2024-02-12T10:00:00', 'latest_time': '2024-02-19T10:00:00', + 'found_incidents_ids': {'1': {'occurred_time': '2024-02-12T09:59:59'}, + '2': {'occurred_time': '2024-02-12T10:00:00'}}} + mock_params = {'fetchQuery': '`notable` is cool', 'fetch_limit': 2} + mocker.patch('demistomock.getLastRun', return_value=mock_last_run) + mocker.patch('demistomock.params', return_value=mock_params) + mocker.patch('splunklib.results.JSONResultsReader', return_value=[self.notable1, + self.notable2]) + service = self.Service() + set_last_run_mocker = mocker.patch('demistomock.setLastRun') + mapper = UserMappingObject(service, False) + splunk.fetch_incidents(service, mapper, 'from_xsoar', 'from_splunk') + last_fetched_ids = set_last_run_mocker.call_args_list[0][0][0]['found_incidents_ids'] + assert last_fetched_ids == {'2': {'occurred_time': '2024-02-12T10:00:00'}, + '3': {'occurred_time': '2024-02-12T10:00:00'}, + '4': {'occurred_time': '2024-02-12T10:00:00'}} + + class TestFetchForLateIndexedEvents: notable1 = {'status': '5', 'event_id': 'id_1'} notable2 = {'status': '6', 'event_id': 'id_2'} diff --git a/Packs/SplunkPy/ReleaseNotes/3_1_20.md b/Packs/SplunkPy/ReleaseNotes/3_1_20.md new file mode 100644 index 000000000000..17c48d05553b --- /dev/null +++ b/Packs/SplunkPy/ReleaseNotes/3_1_20.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### SplunkPy + +- Fixed an issue where the integration would fetch the same incident twice. +- Updated the Docker image to *demisto/splunksdk-py3:1.0.0.87498*. diff --git a/Packs/SplunkPy/pack_metadata.json b/Packs/SplunkPy/pack_metadata.json index a686ad910c9e..32a0bae8b278 100644 --- a/Packs/SplunkPy/pack_metadata.json +++ b/Packs/SplunkPy/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Splunk", "description": "Run queries on Splunk servers.", "support": "xsoar", - "currentVersion": "3.1.19", + "currentVersion": "3.1.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 6d5b0fadc9fd918047d42fc765face00c3c94503 Mon Sep 17 00:00:00 2001 From: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Date: Wed, 28 Feb 2024 17:35:34 +0200 Subject: [PATCH 107/272] [AzureLogAnalytics] update docs (#33076) * test * fix README.md * update desc * update docs * update * Update Packs/AzureLogAnalytics/ReleaseNotes/1_1_27.md * cr updates --- .../AzureLogAnalytics_description.md | 17 ++-- .../Integrations/AzureLogAnalytics/README.md | 78 ++++++++++--------- .../AzureLogAnalytics/ReleaseNotes/1_1_27.md | 5 ++ Packs/AzureLogAnalytics/pack_metadata.json | 2 +- 4 files changed, 56 insertions(+), 46 deletions(-) create mode 100644 Packs/AzureLogAnalytics/ReleaseNotes/1_1_27.md diff --git a/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/AzureLogAnalytics_description.md b/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/AzureLogAnalytics_description.md index a9d71488725c..eeff642a6a24 100644 --- a/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/AzureLogAnalytics_description.md +++ b/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/AzureLogAnalytics_description.md @@ -2,18 +2,19 @@ Log Analytics is a service that helps you collect and analyze data generated by Full documentation for this integration is available in the [reference docs](https://xsoar.pan.dev/docs/reference/integrations/azure-log-analytics). +There are two authentication methods available: -## Authorize Cortex XSOAR for Azure Log Analytics + * [Cortex XSOAR Application](https://xsoar.pan.dev/docs/reference/articles/microsoft-integrations---authentication#cortex-xsoar-application) + * [Self-Deployed Application](https://xsoar.pan.dev/docs/reference/articles/microsoft-integrations---authentication#self-deployed-application) -You need to grant Cortex XSOAR authorization to access Azure Log Analytics. +Depending on the authentication method that you use, the integration parameters might change. -1. Access the [authorization flow](https://oproxy.demisto.ninja/ms-azure-log-analytics). -2. Click the **Start Authorization Process** button. - You will be prompted to grant Cortex XSOAR permissions for your Azure Service Management. -3. Click the **Accept** button. - You will receive your ID, token, and key. You need to enter this information, when you configure the Azure Log Analytics integration instance in Cortex XSOAR. +#### Cortex XSOAR Azure App -## Authorize Cortex XSOAR for Azure Log Analytics - Self-Deployed Configuration +To use the **Cortex XSOAR application** and allow Cortex XSOAR access to Azure Log Analytics, an administrator has to approve our app using an admin consent flow by clicking this **[link](https://oproxy.demisto.ninja/ms-azure-log-analytics)**. +After authorizing the Cortex XSOAR app, you will get an ID, Token, and Key which should be inserted in the integration instance settings fields. + +#### Self-Deployed Azure App To use a self-configured Azure application, you need to add a new Azure App Registration in the Azure Portal. To add the registration, go to the [Microsoft article](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app). ### Required permissions diff --git a/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/README.md b/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/README.md index 087fde07d942..f72675b9d7da 100644 --- a/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/README.md +++ b/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/README.md @@ -1,9 +1,10 @@ Log Analytics is a service that helps you collect and analyze data generated by resources in your cloud and on-premises environments. This integration was integrated and tested with version 2022-10-01 of Azure Log Analytics. -## Authorize Cortex XSOAR for Azure Log Analytics +# Authorization +In order to connect to the Azure Log Analytics use either the Cortex XSOAR Azure App or the Self-Deployed Azure App. -You need to grant Cortex XSOAR authorization to access Azure Log Analytics. +Depending on the authentication method that you use, the integration parameters might change. **Note**: The Azure account must have permission to manage applications in Azure Active Directory (Azure AD). Any of the following Azure AD roles include the required permissions: @@ -11,19 +12,22 @@ You need to grant Cortex XSOAR authorization to access Azure Log Analytics. - Application developer - Cloud application administrator -In addition, the user needs to be assigned the **Log Analytics Reader** role. -To add the role, see the [Microsoft article](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps#assign-users-and-groups-to-roles). +In addition, the user that granted the authorization needs to be assigned the [**Log Analytics Reader** role](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/manage-access?tabs=portal#log-analytics-reader). +For the search job commands the user needs to be assigned the [**Log Analytics Contributor** role](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/manage-access?tabs=portal#log-analytics-contributor). + + To add these roles: + 1. In the Azure portal, go to `Log Analytics workspace` and select the workspace you are using -> Access control (IAM). + 2. From Access control (IAM) select: Add role assignment + 3. Select the user that granted the authorization and assign the Roles. -For the search job commands the user needs to be assigned the [**Log Analytics Contributor** role](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/manage-access?tabs=portal#log-analytics-contributor). -To add the role, see the [Microsoft article](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps#assign-users-and-groups-to-roles) +For more information, refer to the following [Microsoft article](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/api/access-api#set-up-authentication). -1. Access the [authorization flow](https://oproxy.demisto.ninja/ms-azure-log-analytics). -2. Click **Start Authorization Process**. - You will be prompted to grant Cortex XSOAR permissions for your Azure Service Management. -3. Click **Accept**. -You will receive your ID, token, and key. You need to enter these when you configure the Azure Log Analytics integration instance in Cortex XSOAR. +## Cortex XSOAR Azure Application + +You need to grant Cortex XSOAR authorization to access Azure Log Analytics. +For more information, refer to the following [article](https://xsoar.pan.dev/docs/reference/articles/microsoft-integrations---authentication#cortex-xsoar-application). -## Authorize Cortex XSOAR for Azure Log Analytics (Self-Deployed Configuration) +## Self Deployed Application To use a self-configured Azure application, you need to add a new Azure App Registration in the Azure Portal. To add the registration, see the [Microsoft article](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app). @@ -42,7 +46,7 @@ In the self-deployed mode you can authenticate, by using one of the following fl --- 1. In the instance configuration, select the **Use a self-deployed Azure application - Authorization Code flow** checkbox. -2. Enter your client ID in the **ID \ Client ID** parameter (credentials username). +2. Enter your client ID in the **ID / Client ID** parameter (credentials username). 3. Enter your client secret in the **Key / Client Secret** parameter (credentials password). 4. Enter your tenant ID in the **Token** parameter. 5. Enter your redirect URI in the **Redirect URI** parameter. @@ -134,16 +138,16 @@ Executes an Analytics query for data. #### Human Readable Output -## Query Results +>## Query Results -### PrimaryResult +>### PrimaryResult -|Tenant Id|Computer|Time Generated|Source System|Start Time|End Time|Resource Uri|Data Type|Solution|Batches Within Sla|Batches Outside Sla|Batches Capped|Total Batches|Avg Latency In Seconds|Quantity|Quantity Unit|Is Billable|Meter Id|Linked Meter Id|Type| -|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| -| TENANT_ID | Deprecated field: see | 2020-07-30T04:00:00Z | OMS | 2020-07-30T03:00:00Z | 2020-07-30T04:00:00Z | /subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME | Operation | LogManagement | 0 | 0 | 0 | 0 | 0 | 0.00714 | MBytes | false | METER_ID | 00000000-0000-0000-0000-000000000000 | Usage | -| TENANT_ID | Deprecated field: see | 2020-07-30T04:00:00Z | OMS | 2020-07-30T03:00:00Z | 2020-07-30T04:00:00Z | /subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME | SigninLogs | LogManagement | 0 | 0 | 0 | 0 | 0 | 0.012602 | MBytes | true | METER_ID | 00000000-0000-0000-0000-000000000000 | Usage | -| TENANT_ID | Deprecated field: see | 2020-07-30T05:00:00Z | OMS | 2020-07-30T04:00:00Z | 2020-07-30T05:00:00Z | /subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME | OfficeActivity | Office365/SecurityInsights | 0 | 0 | 0 | 0 | 0 | 0.00201499908978072 | MBytes | false | METER_ID | 00000000-0000-0000-0000-000000000000 | Usage | -| TENANT_ID | Deprecated field: see | 2020-07-30T05:00:00Z | OMS | 2020-07-30T04:00:00Z | 2020-07-30T05:00:00Z | /subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME | SigninLogs | LogManagement | 0 | 0 | 0 | 0 | 0 | 0.009107 | MBytes | true | METER_ID | 00000000-0000-0000-0000-000000000000 | Usage | +>|Tenant Id|Computer|Time Generated|Source System|Start Time|End Time|Resource Uri|Data Type|Solution|Batches Within Sla|Batches Outside Sla|Batches Capped|Total Batches|Avg Latency In Seconds|Quantity|Quantity Unit|Is Billable|Meter Id|Linked Meter Id|Type| +>|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +>| TENANT_ID | Deprecated field: see | 2020-07-30T04:00:00Z | OMS | 2020-07-30T03:00:00Z | 2020-07-30T04:00:00Z | /subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME | Operation | LogManagement | 0 | 0 | 0 | 0 | 0 | 0.00714 | MBytes | false | METER_ID | 00000000-0000-0000-0000-000000000000 | Usage | +>| TENANT_ID | Deprecated field: see | 2020-07-30T04:00:00Z | OMS | 2020-07-30T03:00:00Z | 2020-07-30T04:00:00Z | /subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME | SigninLogs | LogManagement | 0 | 0 | 0 | 0 | 0 | 0.012602 | MBytes | true | METER_ID | 00000000-0000-0000-0000-000000000000 | Usage | +>| TENANT_ID | Deprecated field: see | 2020-07-30T05:00:00Z | OMS | 2020-07-30T04:00:00Z | 2020-07-30T05:00:00Z | /subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME | OfficeActivity | Office365/SecurityInsights | 0 | 0 | 0 | 0 | 0 | 0.00201499908978072 | MBytes | false | METER_ID | 00000000-0000-0000-0000-000000000000 | Usage | +>| TENANT_ID | Deprecated field: see | 2020-07-30T05:00:00Z | OMS | 2020-07-30T04:00:00Z | 2020-07-30T05:00:00Z | /subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME | SigninLogs | LogManagement | 0 | 0 | 0 | 0 | 0 | 0.009107 | MBytes | true | METER_ID | 00000000-0000-0000-0000-000000000000 | Usage | ### azure-log-analytics-test @@ -169,7 +173,7 @@ There is no context output for this command. #### Human Readable Output -```✅ Success!``` +>```✅ Success!``` ### azure-log-analytics-list-saved-searches @@ -214,13 +218,13 @@ Gets the saved searches of the Log Analytics workspace. #### Human Readable Output -### Saved searches +>### Saved searches -|Etag|Id|Category|Display Name|Function Alias|Function Parameters|Query|Tags|Version|Type| -|---|---|---|---|---|---|---|---|---|---| -| W/"datetime'2020-07-05T13%3A38%3A41.053438Z'" | test2 | category1 | test2 | heartbeat_func | a:int=1 | Heartbeat \| summarize Count() by Computer \| take a | {'name': 'Group', 'value': 'Computer'} | 2 | Microsoft.OperationalInsights/savedSearches | -| W/"datetime'2020-07-28T18%3A43%3A56.8625448Z'" | test123 | Saved Search Test Category | test123 | heartbeat_func | a:int=1 | Heartbeat \| summarize Count() by Computer \| take a | {'name': 'Group', 'value': 'Computer'} | 2 | Microsoft.OperationalInsights/savedSearches | -| W/"datetime'2020-07-30T11%3A41%3A35.1459664Z'" | test1234 | test | test | | | SecurityAlert
    \| summarize arg_max(TimeGenerated, *) by SystemAlertId
    \| where SystemAlertId in("TEST_SYSTEM_ALERT_ID") | | 2 | Microsoft.OperationalInsights/savedSearches | +>|Etag|Id|Category|Display Name|Function Alias|Function Parameters|Query|Tags|Version|Type| +>|---|---|---|---|---|---|---|---|---|---| +>| W/"datetime'2020-07-05T13%3A38%3A41.053438Z'" | test2 | category1 | test2 | heartbeat_func | a:int=1 | Heartbeat \| summarize Count() by Computer \| take a | {'name': 'Group', 'value': 'Computer'} | 2 | Microsoft.OperationalInsights/savedSearches | +>| W/"datetime'2020-07-28T18%3A43%3A56.8625448Z'" | test123 | Saved Search Test Category | test123 | heartbeat_func | a:int=1 | Heartbeat \| summarize Count() by Computer \| take a | {'name': 'Group', 'value': 'Computer'} | 2 | Microsoft.OperationalInsights/savedSearches | +>| W/"datetime'2020-07-30T11%3A41%3A35.1459664Z'" | test1234 | test | test | | | SecurityAlert
    \| summarize arg_max(TimeGenerated, *) by SystemAlertId
    \| where SystemAlertId in("TEST_SYSTEM_ALERT_ID") | | 2 | Microsoft.OperationalInsights/savedSearches | ### azure-log-analytics-get-saved-search-by-id @@ -264,11 +268,11 @@ Gets a specified saved search from the Log Analytics workspace. #### Human Readable Output -### Saved search `test1234` properties +>### Saved search `test1234` properties -|Etag|Id|Category|Display Name|Query|Version| -|---|---|---|---|---|---| -| W/"datetime'2020-07-30T12%3A21%3A05.3197505Z'" | test1234 | test | test | SecurityAlert | summarize arg_max(TimeGenerated, *) by SystemAlertId | where SystemAlertId in("TEST_SYSTEM_ALERT_ID") | 2 | +>|Etag|Id|Category|Display Name|Query|Version| +>|---|---|---|---|---|---| +>| W/"datetime'2020-07-30T12%3A21%3A05.3197505Z'" | test1234 | test | test | SecurityAlert | summarize arg_max(TimeGenerated, *) by SystemAlertId | where SystemAlertId in("TEST_SYSTEM_ALERT_ID") | 2 | ### azure-log-analytics-create-or-update-saved-search @@ -322,11 +326,11 @@ Creates or updates a saved search from the Log Analytics workspace. #### Human Readable Output -### Saved search `test1234` properties +>### Saved search `test1234` properties -|Etag|Id|Category|Display Name|Query|Version| -|---|---|---|---|---|---| -| W/"datetime'2020-07-30T12%3A21%3A05.3197505Z'" | test1234 | test | new display name test | SecurityAlert | summarize arg_max(TimeGenerated, *) by SystemAlertId | where SystemAlertId in("TEST_SYSTEM_ALERT_ID") | 2 | +>|Etag|Id|Category|Display Name|Query|Version| +>|---|---|---|---|---|---| +>| W/"datetime'2020-07-30T12%3A21%3A05.3197505Z'" | test1234 | test | new display name test | SecurityAlert | summarize arg_max(TimeGenerated, *) by SystemAlertId | where SystemAlertId in("TEST_SYSTEM_ALERT_ID") | 2 | ### azure-log-analytics-delete-saved-search @@ -357,7 +361,7 @@ There is no context output for this command. #### Human Readable Output -Successfully deleted the saved search test1234. +>Successfully deleted the saved search test1234. ### azure-log-analytics-generate-login-url diff --git a/Packs/AzureLogAnalytics/ReleaseNotes/1_1_27.md b/Packs/AzureLogAnalytics/ReleaseNotes/1_1_27.md new file mode 100644 index 000000000000..f29316d3f34d --- /dev/null +++ b/Packs/AzureLogAnalytics/ReleaseNotes/1_1_27.md @@ -0,0 +1,5 @@ + +#### Integrations + +##### Azure Log Analytics +Documentation and metadata improvements. \ No newline at end of file diff --git a/Packs/AzureLogAnalytics/pack_metadata.json b/Packs/AzureLogAnalytics/pack_metadata.json index 94ecfecdc837..838236e50fa8 100644 --- a/Packs/AzureLogAnalytics/pack_metadata.json +++ b/Packs/AzureLogAnalytics/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Log Analytics", "description": "Log Analytics is a service that helps you collect and analyze data generated by resources in your cloud and on-premises environments.", "support": "xsoar", - "currentVersion": "1.1.26", + "currentVersion": "1.1.27", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 48c1b49aa4cf7796ec27b7c07856142e2b016274 Mon Sep 17 00:00:00 2001 From: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Date: Wed, 28 Feb 2024 20:10:01 +0200 Subject: [PATCH 108/272] update the setting of DEMISTO_SDK_GRAPH_FORCE_CREATE (#33107) * update DEMISTO_SDK_GRAPH_FORCE_CREATE * fixed * update * test * revert test --- .gitlab/ci/.gitlab-ci.on-push.yml | 5 +++++ .gitlab/ci/.gitlab-ci.sdk-nightly.yml | 4 ---- .gitlab/ci/.gitlab-ci.variables.yml | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitlab/ci/.gitlab-ci.on-push.yml b/.gitlab/ci/.gitlab-ci.on-push.yml index 18909754fdad..052ad3c1f476 100644 --- a/.gitlab/ci/.gitlab-ci.on-push.yml +++ b/.gitlab/ci/.gitlab-ci.on-push.yml @@ -139,6 +139,11 @@ validate-content-conf: - !reference [.create-release-notes-and-common-docs] - !reference [.secrets-fetch] - section_start "Create or update content graph" --collapsed + - | + echo "set DEMISTO_SDK_GRAPH_FORCE_CREATE to true to create graph from scratch" + export DEMISTO_SDK_GRAPH_FORCE_CREATE=true + echo "DEMISTO_SDK_GRAPH_FORCE_CREATE was set to true to create graph from scratch" + echo $DEMISTO_SDK_GRAPH_FORCE_CREATE - echo "Staging the repo to include the private packs in the graph" - git add Packs - echo "Updating the content graph" diff --git a/.gitlab/ci/.gitlab-ci.sdk-nightly.yml b/.gitlab/ci/.gitlab-ci.sdk-nightly.yml index bc79ef9ddf7a..ea6e944cd22a 100644 --- a/.gitlab/ci/.gitlab-ci.sdk-nightly.yml +++ b/.gitlab/ci/.gitlab-ci.sdk-nightly.yml @@ -171,7 +171,6 @@ demisto-sdk-nightly:xsoar-prepare-testing-bucket: needs: [] stage: prepare-testing-bucket script: - - unset DEMISTO_SDK_GRAPH_FORCE_CREATE - !reference [.generic-prepare-testing-bucket, script] - job-done @@ -197,7 +196,6 @@ demisto-sdk-nightly:mpv2-prepare-testing-bucket: needs: [] stage: prepare-testing-bucket script: - - unset DEMISTO_SDK_GRAPH_FORCE_CREATE - !reference [.generic-prepare-testing-bucket, script] - job-done @@ -221,7 +219,6 @@ demisto-sdk-nightly:xpanse-prepare-testing-bucket: needs: [] stage: prepare-testing-bucket script: - - unset DEMISTO_SDK_GRAPH_FORCE_CREATE - !reference [.generic-prepare-testing-bucket, script] - job-done @@ -244,7 +241,6 @@ demisto-sdk-nightly:xsoar-saas-prepare-testing-bucket: needs: [] stage: prepare-testing-bucket script: - - unset DEMISTO_SDK_GRAPH_FORCE_CREATE - !reference [.generic-prepare-testing-bucket, script] - job-done diff --git a/.gitlab/ci/.gitlab-ci.variables.yml b/.gitlab/ci/.gitlab-ci.variables.yml index 639863ec6e36..a4af7160ca66 100644 --- a/.gitlab/ci/.gitlab-ci.variables.yml +++ b/.gitlab/ci/.gitlab-ci.variables.yml @@ -38,7 +38,6 @@ variables: OVERRIDE_ALL_PACKS: "false" TEST_UPLOAD: "true" NATIVE_CANDIDATE_IMAGE: "latest" - DEMISTO_SDK_GRAPH_FORCE_CREATE: "true" # change this when the demisto-sdk update-graph command is stable DEMISTO_SDK_LOG_FILE_PATH: "${ARTIFACTS_FOLDER}/logs" CONTENT_GITLAB_CI: "true" POETRY_VIRTUALENVS_OPTIONS_ALWAYS_COPY: "true" From 8168db705bbbfb0c88e0be29d523472da59ad1a3 Mon Sep 17 00:00:00 2001 From: Guy Afik <53861351+GuyAfik@users.noreply.github.com> Date: Thu, 29 Feb 2024 08:48:53 +0200 Subject: [PATCH 109/272] [Trend Micro Deep Security] - add new commands (#33063) * add trendmicro-create-onceonly-scheduled-task command * add trendmicro-create-onceonly-scheduled-task test * add trendmicro-delete-scheduled-task command * add trendmicro-delete-scheduled-task unit-test * add trendmicro-list-scheduled-ta command * update context * update task_ids for delete command to single task_id * add trendmicro-list-scheduled-task docs * add trendmicro-create-onceonly-scheduled-task docs * add trendmicro-delete-scheduled-task docs * bump rn * do not error when task id isn't found * handle not found * make tasks_id listable delete cmd * improve test * doc fixes * docs * mypy fix * small cr fix * fix create_scheduled_task to fit relvant tasks * remove irrelvant types * fix test * demo fixes * ruff --- .../TrendMicroDeepSecurity/README.md | 160 +++++++++++ .../TrendMicroDeepSecurity.py | 256 ++++++++++++++---- .../TrendMicroDeepSecurity.yml | 102 ++++++- .../TrendMicroDeepSecurity_test.py | 86 +++++- .../TrendMicroDeepSecurity/command_examples | 5 +- .../test_data/scheduled_task.json | 21 ++ .../ReleaseNotes/1_1_0.md | 10 + .../TrendMicroDeepSecurity/pack_metadata.json | 2 +- 8 files changed, 583 insertions(+), 59 deletions(-) create mode 100644 Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/test_data/scheduled_task.json create mode 100644 Packs/TrendMicroDeepSecurity/ReleaseNotes/1_1_0.md diff --git a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/README.md b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/README.md index b60c0a44c911..d07c0113ce6e 100644 --- a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/README.md +++ b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/README.md @@ -24040,3 +24040,163 @@ Reset the value of a certain default policy setting >|---|---| >| antiMalwareSettingConnectedThreatDefenseSuspiciousFileDdanSubmissionEnabled | true | +### trendmicro-list-scheduled-task + +*** +Get information on all scheduled tasks. + +#### Base Command + +`trendmicro-list-scheduled-task` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| task_id | The ID of the task to retrieve. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| TrendMicro.ScheduledTask.name | String | The name of the scheduled task. | +| TrendMicro.ScheduledTask.type | String | The type of the scheduled task. | +| TrendMicro.ScheduledTask.scheduleDetails.timeZone | String | The timezone of the scheduled task. | +| TrendMicro.ScheduledTask.scheduleDetails.recurrenceType | String | The recurrence type of the scheduled task. | +| TrendMicro.ScheduledTask.scheduleDetails.onceOnlyScheduleParameters.startTime | Number | The start time of the scheduled task. | +| TrendMicro.ScheduledTask.enabled | Boolean | Whether the scheduled task is enabled. | +| TrendMicro.ScheduledTask.nextRunTime | Date | The next run time of the scheduled task. | +| TrendMicro.ScheduledTask.scanForMalwareTaskParameters.computerFilter.type | String | The type of the computer filter of the scheduled task. | +| TrendMicro.ScheduledTask.scanForMalwareTaskParameters.computerFilter.computerID | Number | The computer ID of the scheduled task. | +| TrendMicro.ScheduledTask.scanForMalwareTaskParameters.timeout | String | The timeout for the scheduled task. | +| TrendMicro.ScheduledTask.ID | Number | The ID of the scheduled task. | + +#### Command example +```!trendmicro-list-scheduled-task task_id=1``` +#### Context Example +```json +{ + "TrendMicro": { + "ScheduledTask": { + "ID": 1, + "checkForSecurityUpdatesTaskParameters": { + "computerFilter": { + "type": "type" + }, + "timeout": "never" + }, + "enabled": true, + "lastRunTime": 1687185043521, + "name": "Daily check for Security Updates", + "nextRunTime": 1687271400000, + "scheduleDetails": { + "dailyScheduleParameters": { + "frequencyType": "everyday", + "startTime": 1676993400000 + }, + "recurrenceType": "daily", + "timeZone": "some time zone" + }, + "type": "check-for-security-updates" + } + } +} +``` + +#### Human Readable Output + +>### Scheduled Tasks +>|ID|Name|Type|Enabled|Last Run Time| +>|---|---|---|---|---| +>| 1 | Daily check for Security Updates | check-for-security-updates | true | 2023-06-19 14:30:43 | + +### trendmicro-create-onceonly-scheduled-task + +*** +Creates a once-only scheduled task with a specific computer ID and runs it. + +#### Base Command + +`trendmicro-create-onceonly-scan-scheduled-task` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| name | The name of the scheduled task. | Required | +| type | The type of the scheduled task. Possible values are: scan-for-open-ports, send-alert-summary, discover-computers, run-script, send-policy, generate-report, synchronize-directory, synchronize-users, scan-for-recommendations, synchronize-vcenter, scan-for-integrity-changes, scan-for-malware, check-for-security-updates, synchronize-cloud-account, check-for-software-updates, update-suspicious-objects-list. | Required | +| computer_id | The computer ID to create the task on. Can be retrieved from the trendmicro-list-computers command. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| TrendMicro.ScheduledTask.name | String | The name of the scheduled task. | +| TrendMicro.ScheduledTask.type | String | The type of the scheduled task. | +| TrendMicro.ScheduledTask.scheduleDetails.timeZone | String | The timezone of the scheduled task. | +| TrendMicro.ScheduledTask.scheduleDetails.recurrenceType | String | The recurrence type of the scheduled task. | +| TrendMicro.ScheduledTask.scheduleDetails.onceOnlyScheduleParameters.startTime | Number | The start time of the scheduled task. | +| TrendMicro.ScheduledTask.enabled | Boolean | Whether the scheduled task is enabled. | +| TrendMicro.ScheduledTask.nextRunTime | Date | The next run time of the scheduled task. | +| TrendMicro.ScheduledTask.scanForMalwareTaskParameters.computerFilter.type | String | The type of the computer filter of the scheduled task. | +| TrendMicro.ScheduledTask.scanForMalwareTaskParameters.computerFilter.computerID | Number | The computer ID of the scheduled task. | +| TrendMicro.ScheduledTask.scanForMalwareTaskParameters.timeout | String | The timeout for the scheduled task. | +| TrendMicro.ScheduledTask.ID | Number | The ID of the scheduled task. | + +#### Command example +```!trendmicro-create-onceonly-scheduled-task name=test computer_id=1 type="scan-for-malware"``` +#### Context Example +```json +{ + "TrendMicro": { + "ScheduledTask": { + "ID": 26, + "enabled": true, + "name": "test", + "nextRunTime": 1708620132041, + "scanForMalwareTaskParameters": { + "computerFilter": { + "computerID": 1, + "type": "some type" + }, + "timeout": "never" + }, + "scheduleDetails": { + "onceOnlyScheduleParameters": { + "startTime": 0 + }, + "recurrenceType": "none", + "timeZone": "some time zone" + }, + "type": "scan-for-malware" + } + } +} +``` + +#### Human Readable Output + +>Once-only scheduled task, named test for the computer ID 1 has been successfully created and run. +### trendmicro-delete-scheduled-task + +*** +Deletes a scheduled task. + +#### Base Command + +`trendmicro-delete-scheduled-task` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| task_ids | A comma seperated of task-IDs to delete. | Required | + +#### Context Output + +There is no context output for this command. +#### Command example +```!trendmicro-delete-scheduled-task task_id=1``` +#### Human Readable Output + +>Scheduled task with ID 1 has been successfully deleted. diff --git a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity.py b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity.py index f42c49e2b96d..085be8afff61 100644 --- a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity.py +++ b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity.py @@ -2,7 +2,8 @@ from CommonServerPython import * from CommonServerUserPython import * -from typing import Any, Dict, List, get_type_hints, get_origin, get_args, Callable, Type, no_type_check +from typing import Any, get_type_hints, get_origin, get_args, no_type_check +from collections.abc import Callable import urllib3 from requests.exceptions import ConnectionError, InvalidURL, InvalidSchema, HTTPError @@ -37,7 +38,7 @@ def __init__(self, base_url: str, api_key: str, use_ssl: bool, use_proxy: bool): headers = {"api-secret-key": api_key, "api-version": self.API_VERSION} super().__init__(f"{base_url}/api", verify=use_ssl, proxy=use_proxy, headers=headers) - def list_computers(self, expand: List[str], overrides: bool) -> List[Dict[str, Any]]: + def list_computers(self, expand: list[str], overrides: bool) -> list[dict[str, Any]]: """ List all registered computers inside Trend Micro. @@ -52,7 +53,7 @@ def list_computers(self, expand: List[str], overrides: bool) -> List[Dict[str, A params = {"expand": expand, "overrides": overrides} return self._http_request(method="GET", url_suffix="/computers", params=params).get("computers", []) - def create_computer(self, expand: list, overrides: bool, **computer_properties) -> Dict[str, Any]: + def create_computer(self, expand: list, overrides: bool, **computer_properties) -> dict[str, Any]: """ Create a new computer inside Trend Micro. @@ -68,7 +69,7 @@ def create_computer(self, expand: list, overrides: bool, **computer_properties) params = {"expand": expand, "overrides": overrides} return self._http_request(method="POST", url_suffix="/computers", params=params, json_data=computer_properties) - def get_computer(self, computer_id: int, expand: List[str], overrides: bool) -> Dict[str, Any]: + def get_computer(self, computer_id: int, expand: list[str], overrides: bool) -> dict[str, Any]: """ Get information about an existing computer inside Trend Micro. @@ -84,8 +85,8 @@ def get_computer(self, computer_id: int, expand: List[str], overrides: bool) -> params = {"expand": expand, "overrides": overrides} return self._http_request(method="GET", url_suffix=f"/computers/{computer_id}", params=params) - def modify_computer(self, computer_id: int, expand: List[str], overrides: bool, - **computer_properties) -> Dict[str, Any]: + def modify_computer(self, computer_id: int, expand: list[str], overrides: bool, + **computer_properties) -> dict[str, Any]: """ Modify properties of an existing computer inside Trend Micro. @@ -113,7 +114,7 @@ def delete_computer(self, computer_id: int): self._http_request(method="DELETE", url_suffix=f"/computers/{computer_id}", resp_type="response") - def get_computer_setting(self, computer_id: int, setting_name: str, overrides: bool) -> Dict[str, Any]: + def get_computer_setting(self, computer_id: int, setting_name: str, overrides: bool) -> dict[str, Any]: """ Get information about a certain setting of an existing computer inside Trend Micro. @@ -131,7 +132,7 @@ def get_computer_setting(self, computer_id: int, setting_name: str, overrides: b params=params) def modify_computer_setting(self, computer_id: int, setting_name: str, overrides: bool, - value: str) -> Dict[str, Any]: + value: str) -> dict[str, Any]: """ Modify the setting of an existing computer inside Trend Micro. @@ -147,7 +148,7 @@ def modify_computer_setting(self, computer_id: int, setting_name: str, overrides return self._http_request(method="POST", url_suffix=f"/computers/{computer_id}/settings/{setting_name}", params={"overrides": overrides}, json_data={"value": value}) - def reset_computer_setting(self, computer_id: int, setting_name: str, overrides: bool) -> Dict[str, Any]: + def reset_computer_setting(self, computer_id: int, setting_name: str, overrides: bool) -> dict[str, Any]: """ Reset the setting of an existing computer inside Trend Micro. @@ -162,7 +163,7 @@ def reset_computer_setting(self, computer_id: int, setting_name: str, overrides: return self._http_request(method="DELETE", url_suffix=f"/computers/{computer_id}/settings/{setting_name}", params={"overrides": overrides}) - def list_firewall_rule_ids_of_computer(self, computer_id: int, overrides: bool) -> List[int]: + def list_firewall_rule_ids_of_computer(self, computer_id: int, overrides: bool) -> list[int]: """ Get all rule IDs that are assigned to the computer. @@ -177,7 +178,7 @@ def list_firewall_rule_ids_of_computer(self, computer_id: int, overrides: bool) return self._http_request(method="GET", url_suffix=f"/computers/{computer_id}/firewall/assignments", params={"overrides": overrides}).get("assignedRuleIDs", []) - def add_firewall_rule_ids_to_computer(self, computer_id: int, rule_ids: List[int], overrides: bool) -> List[int]: + def add_firewall_rule_ids_to_computer(self, computer_id: int, rule_ids: list[int], overrides: bool) -> list[int]: """ Assign more rule IDs to a certain computer. @@ -194,7 +195,7 @@ def add_firewall_rule_ids_to_computer(self, computer_id: int, rule_ids: List[int params={"overrides": overrides}, json_data={"rule_ids": rule_ids}).get("assignedRuleIDs", []) - def set_firewall_rule_ids_to_computer(self, computer_id: int, rule_ids: List[int], overrides: bool) -> List[int]: + def set_firewall_rule_ids_to_computer(self, computer_id: int, rule_ids: list[int], overrides: bool) -> list[int]: """ Assign the rule IDs to a certain computer. @@ -223,7 +224,7 @@ def remove_firewall_rule_id_from_computer(self, computer_id: int, firewall_rule_ self._http_request(method="DELETE", url_suffix=f"/computers/{computer_id}/firewall/assignments/{firewall_rule_id}") - def list_computer_groups(self) -> List[Dict[str, Any]]: + def list_computer_groups(self) -> list[dict[str, Any]]: """ List all computer groups inside Trend Micro. @@ -233,7 +234,7 @@ def list_computer_groups(self) -> List[Dict[str, Any]]: return self._http_request(method="GET", url_suffix="/computergroups").get("computerGroups", []) - def create_computer_group(self, **computer_group_properties) -> Dict[str, Any]: + def create_computer_group(self, **computer_group_properties) -> dict[str, Any]: """ Create a new computer group inside Trend Micro. @@ -246,7 +247,7 @@ def create_computer_group(self, **computer_group_properties) -> Dict[str, Any]: return self._http_request(method="POST", url_suffix="/computergroups", json_data=computer_group_properties) - def get_computer_group(self, computer_group_id: int) -> Dict[str, Any]: + def get_computer_group(self, computer_group_id: int) -> dict[str, Any]: """ Get information about a certain computer group. @@ -259,7 +260,7 @@ def get_computer_group(self, computer_group_id: int) -> Dict[str, Any]: return self._http_request(method="GET", url_suffix=f"/computergroups/{computer_group_id}") - def modify_computer_group(self, computer_group_id: int, **computer_group_properties) -> Dict[str, Any]: + def modify_computer_group(self, computer_group_id: int, **computer_group_properties) -> dict[str, Any]: """ Modify a certain computer group properties. @@ -284,7 +285,7 @@ def delete_computer_group(self, computer_group_id: int): self._http_request(method="DELETE", url_suffix=f"/computergroups/{computer_group_id}", resp_type="response") - def list_firewall_rules(self) -> List[Dict[str, Any]]: + def list_firewall_rules(self) -> list[dict[str, Any]]: """ List all firewall rules inside Trend Micro. @@ -294,7 +295,7 @@ def list_firewall_rules(self) -> List[Dict[str, Any]]: return self._http_request(method="GET", url_suffix="/firewallrules").get("firewallRules", []) - def create_firewall_rule(self, **firewall_rule_properties) -> Dict[str, Any]: + def create_firewall_rule(self, **firewall_rule_properties) -> dict[str, Any]: """ Create a new firewall rule. @@ -307,7 +308,7 @@ def create_firewall_rule(self, **firewall_rule_properties) -> Dict[str, Any]: return self._http_request(method="POST", url_suffix="/firewallrules", json_data=firewall_rule_properties) - def get_firewall_rule(self, firewall_rule_id: int) -> Dict[str, Any]: + def get_firewall_rule(self, firewall_rule_id: int) -> dict[str, Any]: """ Get information about a certain firewall rule. @@ -320,7 +321,7 @@ def get_firewall_rule(self, firewall_rule_id: int) -> Dict[str, Any]: return self._http_request(method="GET", url_suffix=f"/firewallrules/{firewall_rule_id}") - def modify_firewall_rule(self, firewall_rule_id: int, **firewall_rule_properties) -> Dict[str, Any]: + def modify_firewall_rule(self, firewall_rule_id: int, **firewall_rule_properties) -> dict[str, Any]: """ Modify a certain firewall rule properties. @@ -346,7 +347,7 @@ def delete_firewall_rule(self, firewall_rule_id: int): self._http_request(method="DELETE", url_suffix=f"/firewallrules/{firewall_rule_id}", resp_type="response") def search(self, resource: str, max_items: int, field_name: str, field_type: str, operation: str, value: str, - sort_by_object_id: Optional[bool]) -> List[Dict[str, Any]]: + sort_by_object_id: Optional[bool]) -> list[dict[str, Any]]: """ Search a resource, such as computers, by a query on a certain field. @@ -372,7 +373,7 @@ def search(self, resource: str, max_items: int, field_name: str, field_type: str return self._http_request(method="POST", url_suffix=f"/{resource.lower()}/search", json_data=body).get(resource, []) - def get_policy(self, policy_id: int, overrides: bool) -> Dict[str, Any]: + def get_policy(self, policy_id: int, overrides: bool) -> dict[str, Any]: """ Get information about a certain policy. @@ -386,7 +387,7 @@ def get_policy(self, policy_id: int, overrides: bool) -> Dict[str, Any]: return self._http_request(method="GET", url_suffix=f"/policies/{policy_id}", params={"overrides": overrides}) - def modify_policy(self, policy_id: int, overrides: bool, **policy_properties) -> Dict[str, Any]: + def modify_policy(self, policy_id: int, overrides: bool, **policy_properties) -> dict[str, Any]: """ Modify the properties of a certain policy. @@ -412,7 +413,7 @@ def delete_policy(self, policy_id: int): self._http_request(method="DELETE", url_suffix=f"/policies/{policy_id}", resp_type="response") - def get_default_policy_setting(self, name: str) -> Dict[str, Any]: + def get_default_policy_setting(self, name: str) -> dict[str, Any]: """ Get information about a certain default setting of Trend Micro's policies. @@ -425,7 +426,7 @@ def get_default_policy_setting(self, name: str) -> Dict[str, Any]: return self._http_request(method="GET", url_suffix=f"/policies/default/settings/{name}") - def modify_default_policy_setting(self, name: str, value: str) -> Dict[str, Any]: + def modify_default_policy_setting(self, name: str, value: str) -> dict[str, Any]: """ Modify a certain default setting of Trend Micro's policies. @@ -440,7 +441,7 @@ def modify_default_policy_setting(self, name: str, value: str) -> Dict[str, Any] return self._http_request(method="POST", url_suffix=f"/policies/default/settings/{name}", json_data={"value": value}) - def reset_default_policy_setting(self, name: str) -> Dict[str, Any]: + def reset_default_policy_setting(self, name: str) -> dict[str, Any]: """ Reset a certain default setting of Trend Micro's policies. @@ -453,7 +454,7 @@ def reset_default_policy_setting(self, name: str) -> Dict[str, Any]: return self._http_request(method="DELETE", url_suffix=f"/policies/default/settings/{name}") - def list_default_policy_settings(self) -> Dict[str, Dict[str, str]]: + def list_default_policy_settings(self) -> dict[str, dict[str, str]]: """ Get all default settings of Trend Micro's settings. @@ -479,7 +480,7 @@ def get_policy_setting(self, policy_id: int, name: str, overrides: bool): return self._http_request(method="GET", url_suffix=f"/policies/{policy_id}/settings/{name}", params={"overrides": overrides}) - def modify_policy_setting(self, policy_id: int, name: str, overrides: bool, value: str) -> Dict[str, Any]: + def modify_policy_setting(self, policy_id: int, name: str, overrides: bool, value: str) -> dict[str, Any]: """ Modify the value of a setting of a certain policy. @@ -496,7 +497,7 @@ def modify_policy_setting(self, policy_id: int, name: str, overrides: bool, valu return self._http_request(method="POST", url_suffix=f"/policies/{policy_id}/settings/{name}", params={"overrides": overrides}, json_data={"value": value}) - def reset_policy_setting(self, policy_id: int, name: str, overrides: bool) -> Dict[str, Any]: + def reset_policy_setting(self, policy_id: int, name: str, overrides: bool) -> dict[str, Any]: """ Reset the value of a setting of a certain policy. @@ -512,7 +513,7 @@ def reset_policy_setting(self, policy_id: int, name: str, overrides: bool) -> Di return self._http_request(method="DELETE", url_suffix=f"/policies/{policy_id}/settings/{name}", params={"overrides": overrides}) - def list_policies(self, overrides: bool) -> List[Dict[str, Any]]: + def list_policies(self, overrides: bool) -> list[dict[str, Any]]: """ List all existing policies inside Trend Micro. @@ -526,7 +527,7 @@ def list_policies(self, overrides: bool) -> List[Dict[str, Any]]: return self._http_request(method="GET", url_suffix="/policies", params={"overrides": overrides}).get("policies", []) - def create_policy(self, overrides: bool, **policy_properties) -> Dict[str, Any]: + def create_policy(self, overrides: bool, **policy_properties) -> dict[str, Any]: """ Create a new policy inside Trend Micro. @@ -541,6 +542,54 @@ def create_policy(self, overrides: bool, **policy_properties) -> Dict[str, Any]: return self._http_request(method="POST", url_suffix="/policies", params={"overrides": overrides}, json_data=policy_properties) + def create_scheduled_task(self, name: str, _type: str, computer_id: int) -> dict: + _type_to_parameter = { + "scan-for-open-ports": "scanForOpenPortsTaskParameters", + "scan-for-recommendations": "scanForRecommendationsTaskParameters", + "scan-for-integrity-changes": "scanForIntegrityChangesTaskParameters", + "scan-for-malware": "scanForMalwareTaskParameters", + } + + body = { + "name": name, + "type": _type, + "scheduleDetails": { + "recurrenceType": "none", + "onceOnlyScheduleParameters": { + "startTime": 0 + } + }, + "runNow": True, + "enabled": True, + _type_to_parameter[_type]: { + "computerFilter": { + "type": "computer", + "computerID": computer_id + }, + "timeout": "never" + } + } + + return super()._http_request( + method="POST", url_suffix="/scheduledtasks", json_data=body + ) + + def delete_scheduled_task(self, task_id: int): + + response = super()._http_request( + method="DELETE", url_suffix=f"/scheduledtasks/{task_id}", resp_type="response" + ) + response.raise_for_status() + return response + + def list_scheduled_tasks(self, task_id: Optional[int] = None) -> requests.Response: + url_suffix = '/scheduledtasks' + if task_id: + url_suffix = f'{url_suffix}/{task_id}' + return self._http_request( + method="GET", url_suffix=url_suffix, resp_type="response", ok_codes=(200, 404) + ) + @no_type_check def _http_request(self, method: str, url_suffix: str = "", params: dict = None, json_data: dict = None, **kwargs): """ @@ -587,7 +636,7 @@ def _convert_value(arg: Any) -> Any: return arg -def convert_arg(value: Optional[str], type_hint: Type) -> Any: +def convert_arg(value: Optional[str], type_hint: type) -> Any: """ Converting a single argument from string into its real type. @@ -602,7 +651,7 @@ def convert_arg(value: Optional[str], type_hint: Type) -> Any: Any: The argument after conversion. """ - converters: Dict[Type, Callable] = {str: str, bool: argToBoolean, int: arg_to_number, list: argToList} + converters: dict[type, Callable] = {str: str, bool: argToBoolean, int: arg_to_number, list: argToList} origin_type_hint = get_origin(type_hint) or type_hint type_hint_args = get_args(type_hint) @@ -615,7 +664,7 @@ def convert_arg(value: Optional[str], type_hint: Type) -> Any: raise ValueError(f"Failed to convert {value} to {origin_type_hint}") -def convert_args(command_function: Callable, args: Dict[str, str]) -> Dict[str, Any]: +def convert_args(command_function: Callable, args: dict[str, str]) -> dict[str, Any]: """ Converting XSOAR string arguments into their real types (according to the requested command). @@ -633,7 +682,7 @@ def convert_args(command_function: Callable, args: Dict[str, str]) -> Dict[str, return {name: convert_arg(args.get(name), hint) for name, hint in type_hints.items()} -def list_computers_command(client: Client, expand: List[str], overrides: bool) -> CommandResults: +def list_computers_command(client: Client, expand: list[str], overrides: bool) -> CommandResults: """ Get list of all computers from Trend Micro. @@ -682,7 +731,7 @@ def search_computers_command(client: Client, max_items: int, field_name: str, fi readable_output=markdown, raw_response=response) -def create_computer_command(client: Client, expand: List[str], overrides: bool, host_name: str, +def create_computer_command(client: Client, expand: list[str], overrides: bool, host_name: str, display_name: Optional[str], description: Optional[str], group_id: Optional[int], policy_id: Optional[int], asset_importance_id: Optional[int], relay_list_id: Optional[int]) -> CommandResults: @@ -717,7 +766,7 @@ def create_computer_command(client: Client, expand: List[str], overrides: bool, readable_output=markdown, raw_response=response) -def get_computer_command(client: Client, computer_id: int, expand: List[str], overrides: bool) -> CommandResults: +def get_computer_command(client: Client, computer_id: int, expand: list[str], overrides: bool) -> CommandResults: """ Obtain information about an existing computer inside Trend Micro. @@ -740,7 +789,7 @@ def get_computer_command(client: Client, computer_id: int, expand: List[str], ov readable_output=markdown, raw_response=response) -def modify_computer_command(client: Client, computer_id: int, expand: List[str], overrides: bool, +def modify_computer_command(client: Client, computer_id: int, expand: list[str], overrides: bool, host_name: Optional[str], display_name: Optional[str], description: Optional[str], group_id: Optional[int], policy_id: Optional[int], asset_importance_id: Optional[int], relay_list_id: Optional[int]) -> CommandResults: @@ -890,7 +939,7 @@ def list_firewall_rule_ids_of_computer_command(client: Client, computer_id: int, readable_output=markdown, raw_response=response) -def add_firewall_rule_ids_to_computer_command(client: Client, computer_id: int, rule_ids: List[int], +def add_firewall_rule_ids_to_computer_command(client: Client, computer_id: int, rule_ids: list[int], overrides: bool) -> CommandResults: """ Assign more rule IDs to a certain computer. @@ -913,7 +962,7 @@ def add_firewall_rule_ids_to_computer_command(client: Client, computer_id: int, readable_output=markdown, raw_response=response) -def set_firewall_rule_ids_to_computer_command(client: Client, computer_id: int, rule_ids: List[int], +def set_firewall_rule_ids_to_computer_command(client: Client, computer_id: int, rule_ids: list[int], overrides: bool) -> CommandResults: """ Assign rule IDs to a certain computer. @@ -1137,24 +1186,24 @@ def create_firewall_rule_command(client: Client, name: str, description: Optiona protocol_number: Optional[int], protocol_not: Optional[bool], source_ip_type: Optional[str], source_ip_value: Optional[str], source_ip_mask: Optional[str], source_ip_range_from: Optional[str], - source_ip_range_to: Optional[str], source_ip_multiple: Optional[List[str]], + source_ip_range_to: Optional[str], source_ip_multiple: Optional[list[str]], source_ip_list_id: Optional[int], source_ip_not: Optional[bool], source_mac_type: Optional[str], source_mac_value: Optional[str], source_mac_multiple: Optional[list], source_mac_list_id: Optional[int], source_mac_not: Optional[bool], source_port_type: Optional[str], - source_port_multiple: Optional[List[str]], source_port_list_id: Optional[int], + source_port_multiple: Optional[list[str]], source_port_list_id: Optional[int], source_port_not: Optional[bool], destination_ip_type: Optional[str], destination_ip_value: Optional[str], destination_ip_mask: Optional[str], destination_ip_range_from: Optional[str], destination_ip_range_to: Optional[str], destination_ip_multiple: Optional[list], destination_ip_list_id: Optional[int], destination_ip_not: Optional[bool], destination_mac_type: Optional[str], - destination_mac_value: Optional[str], destination_mac_multiple: Optional[List[str]], + destination_mac_value: Optional[str], destination_mac_multiple: Optional[list[str]], destination_mac_list_id: Optional[int], destination_mac_not: Optional[bool], - destination_port_type: Optional[str], destination_port_multiple: Optional[List[str]], + destination_port_type: Optional[str], destination_port_multiple: Optional[list[str]], destination_port_list_id: Optional[int], destination_port_not: Optional[bool], any_flags: Optional[bool], log_disabled: Optional[bool], include_packet_data: Optional[bool], alert_enabled: Optional[bool], - schedule_id: Optional[int], context_id: Optional[int], tcp_flags: Optional[List[str]], + schedule_id: Optional[int], context_id: Optional[int], tcp_flags: Optional[list[str]], tcp_not: Optional[bool], icmp_type: Optional[int], icmp_code: Optional[int], icmp_not: Optional[bool]) -> CommandResults: """ @@ -1288,24 +1337,24 @@ def modify_firewall_rule_command(client: Client, firewall_rule_id: int, name: Op protocol: Optional[str], protocol_number: Optional[int], protocol_not: Optional[bool], source_ip_type: Optional[str], source_ip_value: Optional[str], source_ip_mask: Optional[str], source_ip_range_from: Optional[str], - source_ip_range_to: Optional[str], source_ip_multiple: Optional[List[str]], + source_ip_range_to: Optional[str], source_ip_multiple: Optional[list[str]], source_ip_list_id: Optional[int], source_ip_not: Optional[bool], source_mac_type: Optional[str], source_mac_value: Optional[str], source_mac_multiple: Optional[list], source_mac_list_id: Optional[int], source_mac_not: Optional[bool], source_port_type: Optional[str], - source_port_multiple: Optional[List[str]], source_port_list_id: Optional[int], + source_port_multiple: Optional[list[str]], source_port_list_id: Optional[int], source_port_not: Optional[bool], destination_ip_type: Optional[str], destination_ip_value: Optional[str], destination_ip_mask: Optional[str], destination_ip_range_from: Optional[str], destination_ip_range_to: Optional[str], destination_ip_multiple: Optional[list], destination_ip_list_id: Optional[int], destination_ip_not: Optional[bool], destination_mac_type: Optional[str], - destination_mac_value: Optional[str], destination_mac_multiple: Optional[List[str]], + destination_mac_value: Optional[str], destination_mac_multiple: Optional[list[str]], destination_mac_list_id: Optional[int], destination_mac_not: Optional[bool], - destination_port_type: Optional[str], destination_port_multiple: Optional[List[str]], + destination_port_type: Optional[str], destination_port_multiple: Optional[list[str]], destination_port_list_id: Optional[int], destination_port_not: Optional[bool], any_flags: Optional[bool], log_disabled: Optional[bool], include_packet_data: Optional[bool], alert_enabled: Optional[bool], - schedule_id: Optional[int], context_id: Optional[int], tcp_flags: Optional[List[str]], + schedule_id: Optional[int], context_id: Optional[int], tcp_flags: Optional[list[str]], tcp_not: Optional[bool], icmp_type: Optional[int], icmp_code: Optional[int], icmp_not: Optional[bool]) -> CommandResults: """ @@ -1736,6 +1785,103 @@ def create_policy_command(client: Client, name: str, overrides: bool, parent_id: readable_output=markdown, raw_response=response) +def create_once_only_scan_scheduled_task_command(client: Client, name: str, type: str, computer_id: int): + """ + Creates a scan scheduled task on a computer ID. + + Args: + name (str): the name of the task + type (str): the type of the scheduled task + computer_id (int): the computer ID to run the scheduled task on + """ + response = client.create_scheduled_task(name, _type=type, computer_id=computer_id) + return CommandResults( + outputs_prefix="TrendMicro.ScheduledTask", + outputs_key_field="ID", + raw_response=response, + outputs=response, + readable_output=f"Once-only scheduled task, named {name} for the " + f"computer ID {computer_id} has been successfully created and run." + ) + + +def delete_scheduled_task_command(client: Client, task_ids: List[int]): + """ + Deletes a scheduled task(s) + + Args: + task_ids int: task ID to delete + """ + results = [] + + for task_id in task_ids: + try: + _task_id = arg_to_number(task_id) + if not _task_id: + raise ValueError(f"Could not parse {_task_id} into integer") + except ValueError: + results.append( + CommandResults( + entry_type=EntryType.ERROR, readable_output=f'task-ID {task_id} provided is invalid, must be integer' + ) + ) + else: + try: + client.delete_scheduled_task(_task_id) + results.append( + CommandResults( + readable_output=f"Scheduled task with ID {task_id} has been successfully deleted." + ) + ) + except Exception as error: + demisto.error(f'Failed to delete task-ID {task_id}, {error=}') + results.append( + CommandResults(entry_type=EntryType.ERROR, readable_output=f'Failed to delete {task_id}') + ) + + return results + + +def list_scheduled_task_command(client: Client, task_id: Optional[int]): + """ + Lists all the available scheduled tasks + + Args: + task_id (int): querying for a specific scheduled task-ID. + """ + response = client.list_scheduled_tasks(task_id) + if response.status_code == 404: + return CommandResults( + readable_output=f"Could not find scheduled task with ID {task_id}" + ) + + raw_response = response.json() + context_output = raw_response.get("scheduledTasks") or raw_response + + if isinstance(context_output, dict): + context_output = [context_output] + + if context_output: + return CommandResults( + outputs=context_output, + raw_response=raw_response, + outputs_prefix="TrendMicro.ScheduledTask", + outputs_key_field="ID", + readable_output=tableToMarkdown( + "Scheduled Tasks", + context_output, + headers=["ID", "name", "type", "enabled", "lastRunTime"], + headerTransform=pascalToSpace, + date_fields=["lastRunTime", "nextRunTime"], + removeNull=True + ) + ) + + return CommandResults( + readable_output="There are no existing scheduled tasks." + ) + + def test_module(client: Client, **_) -> str: """ Testing the Trend Micro API. @@ -1764,7 +1910,7 @@ def main(): return_error('API secret must be provided.') client = Client(params.get("server_url"), api_secret, use_ssl, use_proxy) - commands: Dict[str, Callable] = {"trendmicro-list-computers": list_computers_command, + commands: dict[str, Callable] = {"trendmicro-list-computers": list_computers_command, "trendmicro-create-computer": create_computer_command, "trendmicro-search-computers": search_computers_command, "trendmicro-get-computer": get_computer_command, @@ -1801,9 +1947,11 @@ def main(): "trendmicro-modify-policy-setting": modify_policy_setting_command, "trendmicro-reset-policy-setting": reset_policy_setting_command, "trendmicro-list-policies": list_policies_command, - "trendmicro-create-policy": create_policy_command, "test-module": test_module} - - error_message = "" + "trendmicro-create-policy": create_policy_command, + "trendmicro-create-onceonly-scan-scheduled-task": create_once_only_scan_scheduled_task_command, # noqa: E501 + "trendmicro-delete-scheduled-task": delete_scheduled_task_command, + "trendmicro-list-scheduled-task": list_scheduled_task_command, + "test-module": test_module} try: command = demisto.command() diff --git a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity.yml b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity.yml index 0f3b14aa5d22..b08dbf120009 100644 --- a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity.yml +++ b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity.yml @@ -3959,7 +3959,107 @@ script: description: The name of the default policy setting. - contextPath: TrendMicro.DefaultPolicySettings.value description: The value of the default policy setting. - dockerimage: demisto/python3:3.10.13.84405 + - arguments: + - description: The name of the scheduled task. + name: name + required: true + - description: The type of the scheduled task. + name: type + required: true + predefined: + - scan-for-open-ports + - scan-for-recommendations + - scan-for-integrity-changes + - scan-for-malware + auto: PREDEFINED + - description: The computer ID to create the task on. Can be retrieved from the trendmicro-list-computers command. + name: computer_id + required: true + description: Creates a once-only scheduled task with a specific computer ID and runs it. + name: trendmicro-create-onceonly-scan-scheduled-task + outputs: + - contextPath: TrendMicro.ScheduledTask.name + description: The name of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.type + description: The type of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.scheduleDetails.timeZone + description: The timezone of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.scheduleDetails.recurrenceType + description: The recurrence type of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.scheduleDetails.onceOnlyScheduleParameters.startTime + description: The start time of the scheduled task. + type: Number + - contextPath: TrendMicro.ScheduledTask.enabled + description: Whether the scheduled task is enabled. + type: Boolean + - contextPath: TrendMicro.ScheduledTask.nextRunTime + description: The next run time of the scheduled task. + type: Date + - contextPath: TrendMicro.ScheduledTask.scanForMalwareTaskParameters.computerFilter.type + description: The type of the computer filter of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.scanForMalwareTaskParameters.computerFilter.computerID + description: The computer ID of the scheduled task. + type: Number + - contextPath: TrendMicro.ScheduledTask.scanForMalwareTaskParameters.timeout + description: The timeout for the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.ID + description: The ID of the scheduled task. + type: Number + - arguments: + - description: A comma seperated of task-IDs to delete. + name: task_ids + required: true + isArray: true + description: Deletes a scheduled task. + name: trendmicro-delete-scheduled-task + outputs: [] + - arguments: + - description: The ID of the task to retrieve. + name: task_id + required: false + description: Get information on all scheduled tasks. + name: trendmicro-list-scheduled-task + outputs: + - contextPath: TrendMicro.ScheduledTask.name + description: The name of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.type + description: The type of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.scheduleDetails.timeZone + description: The timezone of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.scheduleDetails.recurrenceType + description: The recurrence type of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.scheduleDetails.onceOnlyScheduleParameters.startTime + description: The start time of the scheduled task. + type: Number + - contextPath: TrendMicro.ScheduledTask.enabled + description: Whether the scheduled task is enabled. + type: Boolean + - contextPath: TrendMicro.ScheduledTask.nextRunTime + description: The next run time of the scheduled task. + type: Date + - contextPath: TrendMicro.ScheduledTask.scanForMalwareTaskParameters.computerFilter.type + description: The type of the computer filter of the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.scanForMalwareTaskParameters.computerFilter.computerID + description: The computer ID of the scheduled task. + type: Number + - contextPath: TrendMicro.ScheduledTask.scanForMalwareTaskParameters.timeout + description: The timeout for the scheduled task. + type: String + - contextPath: TrendMicro.ScheduledTask.ID + description: The ID of the scheduled task. + type: Number + dockerimage: demisto/python3:3.10.13.87159 runonce: false subtype: python3 type: python diff --git a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity_test.py b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity_test.py index aedc3b6eae1f..6ebafafcc473 100644 --- a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity_test.py +++ b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/TrendMicroDeepSecurity_test.py @@ -1,12 +1,13 @@ import json -from typing import Any, Dict, List, Union +from typing import Any from TrendMicroDeepSecurity import Client, convert_args +from CommonServerPython import * BASE_URL = "https://test.api.deepsecurity.trendmicro.com" -def load_mock_response(filename: str) -> Union[List[Any], Dict[str, Any]]: +def load_mock_response(filename: str) -> list[Any] | dict[str, Any]: return json.loads(open(f"test_data/{filename}.json").read()) @@ -1002,3 +1003,84 @@ def test_trendmicro_create_policy_command(requests_mock): assert result.outputs_prefix == "TrendMicro.Policies" assert result.outputs["name"] == "TestPolicy" + + +def test_create_once_only_scan_scheduled_task_command(requests_mock): + """ + Scenario: Create a new scheduled task for a computer ID + + Given: + - name, type and computer ID arguments + When: + - create_once_only_scheduled_task_command is called. + Then: + - Ensure outputs prefix is correct. + - Ensure the context is valid (simply the raw api response) + """ + from TrendMicroDeepSecurity import create_once_only_scan_scheduled_task_command + requests_mock.post(f'{BASE_URL}/api/scheduledtasks', json=load_mock_response("scheduled_task")) + client = Client(base_url=BASE_URL, api_key="xxx", use_ssl=False, use_proxy=False) + args = convert_args( + create_once_only_scan_scheduled_task_command, + {"name": "test", "type": "scan-for-open-ports", "computer_id": "123"} + ) + result = create_once_only_scan_scheduled_task_command(client, **args) + + assert result.outputs + assert result.outputs_prefix == "TrendMicro.ScheduledTask" + + +def test_delete_scheduled_task_command(mocker, requests_mock): + """ + Scenario: Deletes scheduled task by task-ID + + Given: + - 1 task ID which was deleted successfully + - 1 task ID which wasn't deleted successfully (error from the api) + - 1 task ID which wasn't deleted successfully (not an integer) + When: + - delete_scheduled_task_command is called + Then: + - Ensure ID 1 has readable output + - Ensure ID 2 returns error entry + - Ensure ID c returns error entry + """ + from TrendMicroDeepSecurity import delete_scheduled_task_command + requests_mock.delete(f'{BASE_URL}/api/scheduledtasks/1', status_code=204) + requests_mock.delete(f'{BASE_URL}/api/scheduledtasks/2', exc=Exception("error")) + mocker.patch.object(demisto, 'error') + client = Client(base_url=BASE_URL, api_key="xxx", use_ssl=False, use_proxy=False) + args = convert_args(delete_scheduled_task_command, {"task_ids": "1,2,c"}) + result = delete_scheduled_task_command(client, **args) + + assert "successfully deleted" in result[0].readable_output + assert result[0].entry_type == EntryType.NOTE + assert result[1].entry_type == EntryType.ERROR + assert result[2].entry_type == EntryType.ERROR + + +def test_list_scheduled_task_command(requests_mock): + """ + Scenario: Lists scheduled tasks + + Given: + - task-id argument + When: + - list_scheduled_task_command is called. + Then: + - Ensure context output and human readable are parsed successfully + """ + + from TrendMicroDeepSecurity import list_scheduled_task_command + + mock_response = load_mock_response("scheduled_task") + requests_mock.get(f"{BASE_URL}/api/scheduledtasks/1", json=mock_response) + + client = Client(base_url=BASE_URL, api_key="xxx", use_ssl=False, use_proxy=False) + args = convert_args(list_scheduled_task_command, {"task_id": "1"}) + result = list_scheduled_task_command(client, **args) + + assert result.outputs + assert isinstance(result.outputs, list) + assert result.readable_output + assert result.outputs_prefix == "TrendMicro.ScheduledTask" diff --git a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/command_examples b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/command_examples index 3e63d6b8dcd1..61fe88a757cc 100644 --- a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/command_examples +++ b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/command_examples @@ -35,4 +35,7 @@ !trendmicro-list-default-policy-settings !trendmicro-get-default-policy-setting name=antiMalwareSettingConnectedThreatDefenseSuspiciousFileDdanSubmissionEnabled !trendmicro-modify-default-policy-setting name=antiMalwareSettingConnectedThreatDefenseSuspiciousFileDdanSubmissionEnabled value=false -!trendmicro-reset-default-policy-setting name=antiMalwareSettingConnectedThreatDefenseSuspiciousFileDdanSubmissionEnabled \ No newline at end of file +!trendmicro-reset-default-policy-setting name=antiMalwareSettingConnectedThreatDefenseSuspiciousFileDdanSubmissionEnabled +!trendmicro-list-scheduled-task task_id=1 +!trendmicro-create-onceonly-scheduled-task name=test computer_id=1 type="scan-for-malware" +!trendmicro-delete-scheduled-task task_id=1 \ No newline at end of file diff --git a/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/test_data/scheduled_task.json b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/test_data/scheduled_task.json new file mode 100644 index 000000000000..e7641e2c295a --- /dev/null +++ b/Packs/TrendMicroDeepSecurity/Integrations/TrendMicroDeepSecurity/test_data/scheduled_task.json @@ -0,0 +1,21 @@ +{ + "name": "test", + "type": "scan-for-malware", + "scheduleDetails": { + "timeZone": "some time zone", + "recurrenceType": "none", + "onceOnlyScheduleParameters": { + "startTime": 0 + } + }, + "enabled": true, + "nextRunTime": 1708615684662, + "scanForMalwareTaskParameters": { + "computerFilter": { + "type": "computer", + "computerID": 111111 + }, + "timeout": "never" + }, + "ID": 1 +} \ No newline at end of file diff --git a/Packs/TrendMicroDeepSecurity/ReleaseNotes/1_1_0.md b/Packs/TrendMicroDeepSecurity/ReleaseNotes/1_1_0.md new file mode 100644 index 000000000000..b58438c9a188 --- /dev/null +++ b/Packs/TrendMicroDeepSecurity/ReleaseNotes/1_1_0.md @@ -0,0 +1,10 @@ + +#### Integrations + +##### Trend Micro Deep Security + +- Added the following commands: + - ***trendmicro-create-onceonly-scheduled-task*** + - ***trendmicro-list-scheduled-task*** + - ***trendmicro-delete-scheduled-task*** +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/TrendMicroDeepSecurity/pack_metadata.json b/Packs/TrendMicroDeepSecurity/pack_metadata.json index 743e1d816bcd..04cdf86365c3 100644 --- a/Packs/TrendMicroDeepSecurity/pack_metadata.json +++ b/Packs/TrendMicroDeepSecurity/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Trend Micro Deep Security", "description": "Trend Micro Deep Security provides runtime security for workloads (physical, virtual, cloud, and containers).", "support": "xsoar", - "currentVersion": "1.0.13", + "currentVersion": "1.1.0", "author": "Cortex XSOAR", "url": "", "email": "", From 585154a85a0acb6c23af012adf5feac02dd53261 Mon Sep 17 00:00:00 2001 From: Sasha Sokolovich <88268646+ssokolovich@users.noreply.github.com> Date: Thu, 29 Feb 2024 09:39:18 +0200 Subject: [PATCH 110/272] CTF report indicator fix (#32948) * updated the question about the report indicator type * RN * Updated MP dependency * Format to CTF01 * Format to CTF02 * RN * RN * RN * RN * RN * RN * Update ReadMe file * Update ReadMe file --- ...-_Classify_an_incident_RDP_Brute_force.yml | 2 +- Packs/CTF02/README.md | 1 + Packs/CTF02/ReleaseNotes/1_0_3.md | 13 + Packs/CTF02/Scripts/CTF2BF/CTF2BF.py | 4 +- Packs/CTF02/Scripts/CTF2BF/CTF2BF.yml | 2 +- Packs/CTF02/pack_metadata.json | 5 +- Packs/ctf01/.pack-ignore | 2 +- .../classifier-XDR_-_Incoming_Mapper_ctf.json | 4 +- .../dashboard-CTF_1_and_2_Dashboard.json | 16 +- .../CortexXDRIRCTF/CortexXDRIRCTF.yml | 2 +- .../Integrations/CortexXDRIRCTF/README.md | 305 ++++++++++++++++++ .../Integrations/OHMYVTCTF/OHMYVTCTF.yml | 3 +- ...ble_External_RDP_Brute-Force_CTF_README.md | 26 +- ...k-Cortex_XDR_Alerts_Handling_CTF_README.md | 17 +- Packs/ctf01/README.md | 1 + Packs/ctf01/ReleaseNotes/1_0_9.md | 36 +++ .../report-Monthly_Report_for_our_CISO.json | 2 +- Packs/ctf01/Scripts/CTF1/CTF1.yml | 2 +- Packs/ctf01/pack_metadata.json | 5 +- 19 files changed, 404 insertions(+), 44 deletions(-) create mode 100644 Packs/CTF02/ReleaseNotes/1_0_3.md create mode 100644 Packs/ctf01/ReleaseNotes/1_0_9.md diff --git a/Packs/CTF02/Playbooks/playbook-CTF_2_-_Classify_an_incident_RDP_Brute_force.yml b/Packs/CTF02/Playbooks/playbook-CTF_2_-_Classify_an_incident_RDP_Brute_force.yml index 28f194352202..e32e512bb624 100644 --- a/Packs/CTF02/Playbooks/playbook-CTF_2_-_Classify_an_incident_RDP_Brute_force.yml +++ b/Packs/CTF02/Playbooks/playbook-CTF_2_-_Classify_an_incident_RDP_Brute_force.yml @@ -503,7 +503,7 @@ tasks: label: "" labelarg: simple: |- - Based on the Campaign's Report Description, what was the year when this campaign was first seen? + Based on the Campaign's Report Description, what was the year when a banking trojan malware associated with this campaign was first seen? To answer - search for the report indicator type associated with that campaign required: false gridcolumns: [] diff --git a/Packs/CTF02/README.md b/Packs/CTF02/README.md index b8047d48d20a..0c3ca99cb9bb 100644 --- a/Packs/CTF02/README.md +++ b/Packs/CTF02/README.md @@ -7,6 +7,7 @@ This pack was prepared with small challenges which enables you to get familiar w To play this game, follow the instructions located within the "Prepare your CTF" playbook, located in the `Capture The Flag - 01` pack. For more information, visit the following references: + - [Prepare your instance for Capture The Flag](https://xsoar.pan.dev/docs/reference/packs/capture-the-flag-preparation) - [Introducing New XSOAR Capture the Flags!](https://www.paloaltonetworks.com/blog/security-operations/introducing-new-xsoar-capture-the-flags/) diff --git a/Packs/CTF02/ReleaseNotes/1_0_3.md b/Packs/CTF02/ReleaseNotes/1_0_3.md new file mode 100644 index 000000000000..bef9c6d7d6f8 --- /dev/null +++ b/Packs/CTF02/ReleaseNotes/1_0_3.md @@ -0,0 +1,13 @@ + +#### Playbooks + +##### CTF 2 - Classify an incident - RDP Brute force + +Updated the question's description about the 'report' indicator type. + +#### Scripts + +##### CTF_2_BF + +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. + diff --git a/Packs/CTF02/Scripts/CTF2BF/CTF2BF.py b/Packs/CTF02/Scripts/CTF2BF/CTF2BF.py index 5b0c29fea700..a0bc103f7462 100644 --- a/Packs/CTF02/Scripts/CTF2BF/CTF2BF.py +++ b/Packs/CTF02/Scripts/CTF2BF/CTF2BF.py @@ -99,14 +99,14 @@ def error_msg(): def main(): try: args = demisto.args() - # __Error handeling when there is an empty secret or question id__ + # __Error handling when there is an empty secret or question id__ question_id = args.get("question_ID") secret = args.get("secret", "").lower() if not secret or not question_id: raise DemistoException('Please specify Secret and Question ID to proceed with the challenge') - # __Validate Quesion number 03__ + # __Validate Question number 03__ match question_id: case "03": diff --git a/Packs/CTF02/Scripts/CTF2BF/CTF2BF.yml b/Packs/CTF02/Scripts/CTF2BF/CTF2BF.yml index 5fa560dc3fc0..e08c96132c21 100644 --- a/Packs/CTF02/Scripts/CTF2BF/CTF2BF.yml +++ b/Packs/CTF02/Scripts/CTF2BF/CTF2BF.yml @@ -26,7 +26,7 @@ args: scripttarget: 0 subtype: python3 runonce: false -dockerimage: demisto/python3:3.10.13.83255 +dockerimage: demisto/python3:3.10.13.87159 runas: DBotWeakRole engineinfo: {} fromversion: 8.2.0 diff --git a/Packs/CTF02/pack_metadata.json b/Packs/CTF02/pack_metadata.json index 77f2ae22777d..8c1e616f4ddb 100644 --- a/Packs/CTF02/pack_metadata.json +++ b/Packs/CTF02/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Capture The Flag - 02", "description": "XSOAR's Capture the flag (CTF)", "support": "xsoar", - "currentVersion": "1.0.2", + "currentVersion": "1.0.3", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", @@ -15,7 +15,8 @@ "useCases": [], "keywords": [], "marketplaces": [ - "xsoar" + "xsoar", + "xsoar_saas" ], "dependencies": { "ctf01": { diff --git a/Packs/ctf01/.pack-ignore b/Packs/ctf01/.pack-ignore index 58dae853f8e1..4f5d1cb524a7 100644 --- a/Packs/ctf01/.pack-ignore +++ b/Packs/ctf01/.pack-ignore @@ -5,7 +5,7 @@ ignore=PB105 ignore=IN136,IN124 [file:CortexXDRIRCTF.yml] -ignore=IN126 +ignore=IN126,IN136 [file:incidentfield-CTF01.json] diff --git a/Packs/ctf01/Classifiers/classifier-XDR_-_Incoming_Mapper_ctf.json b/Packs/ctf01/Classifiers/classifier-XDR_-_Incoming_Mapper_ctf.json index 41663bd9e2f5..c1db36271b9e 100644 --- a/Packs/ctf01/Classifiers/classifier-XDR_-_Incoming_Mapper_ctf.json +++ b/Packs/ctf01/Classifiers/classifier-XDR_-_Incoming_Mapper_ctf.json @@ -366,8 +366,8 @@ "simple": "incident_id" }, "MITRE Tactic Name": { - "simple": "mitre_tactics_ids_and_names" - }, + "simple": "mitre_tactics_ids_and_names" + }, "XDR Low Severity Alert Count": { "simple": "low_severity_alert_count" }, diff --git a/Packs/ctf01/Dashboards/dashboard-CTF_1_and_2_Dashboard.json b/Packs/ctf01/Dashboards/dashboard-CTF_1_and_2_Dashboard.json index 2684b2a7ef18..b55f5494dfdd 100644 --- a/Packs/ctf01/Dashboards/dashboard-CTF_1_and_2_Dashboard.json +++ b/Packs/ctf01/Dashboards/dashboard-CTF_1_and_2_Dashboard.json @@ -593,14 +593,14 @@ } ], "name": "CTF 1 And 2 Dashboard", - "period": { - "by": "", - "byTo": "", - "byFrom": "days", - "toValue": null, - "fromValue": 0, - "field": "" - }, + "period": { + "by": "", + "byTo": "", + "byFrom": "days", + "toValue": null, + "fromValue": 0, + "field": "" + }, "toDate": "0001-01-01T00:00:00Z", "version": -1, "fromVersion": "8.2.0", diff --git a/Packs/ctf01/Integrations/CortexXDRIRCTF/CortexXDRIRCTF.yml b/Packs/ctf01/Integrations/CortexXDRIRCTF/CortexXDRIRCTF.yml index 18064c8a0be1..75fbe0089b8c 100644 --- a/Packs/ctf01/Integrations/CortexXDRIRCTF/CortexXDRIRCTF.yml +++ b/Packs/ctf01/Integrations/CortexXDRIRCTF/CortexXDRIRCTF.yml @@ -725,7 +725,7 @@ script: description: Whether the alert is starred or not. type: Boolean description: "Returns a list of alerts and their metadata, which you can filter by built-in arguments or use the custom_filter to input a JSON filter object. \nMultiple filter arguments will be concatenated using the AND operator, while arguments that support a comma-separated list of values will use an OR operator between each value." - dockerimage: demisto/python3:3.10.13.84405 + dockerimage: demisto/python3:3.10.13.87159 isfetch: true runonce: false subtype: python3 diff --git a/Packs/ctf01/Integrations/CortexXDRIRCTF/README.md b/Packs/ctf01/Integrations/CortexXDRIRCTF/README.md index e69de29bb2d1..bf95f02ed97a 100644 --- a/Packs/ctf01/Integrations/CortexXDRIRCTF/README.md +++ b/Packs/ctf01/Integrations/CortexXDRIRCTF/README.md @@ -0,0 +1,305 @@ +This integration is a Mock customized only for the Capture The Flag challenge. + +## Commands + + +You can execute these commands from the Cortex XSOAR 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. + +### get-mapping-fields + +*** +Gets mapping fields from remote incident. Note: This method will not update the current incident, it's here for debugging purposes. + +#### Base Command + +`get-mapping-fields` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | + +#### Context Output + +There is no context output for this command. +### xdr-get-incident-extra-data-ctf + +*** +Returns additional data for the specified incident, for example, related alerts, file artifacts, network artifacts, and so on. + +#### Base Command + +`xdr-get-incident-extra-data-ctf` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| incident_id | The ID of the incident for which to get additional data. | Required | +| alerts_limit | Maximum number of alerts to return. Default is 1000. | Optional | +| return_only_updated_incident | Return data only if the incident was changed since the last time it was mirrored into Cortex XSOAR. This flag should be used only from within a Cortex XDR incident. Default is False. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| PaloAltoNetworksXDR.Incident.incident_id | String | Unique ID assigned to each returned incident. | +| PaloAltoNetworksXDR.Incident.creation_time | Date | Date and time the incident was created on Cortex XDR. | +| PaloAltoNetworksXDR.Incident.modification_time | Date | Date and time that the incident was last modified. | +| PaloAltoNetworksXDR.Incident.detection_time | Date | Date and time that the first alert occurred in the incident. | +| PaloAltoNetworksXDR.Incident.status | String | Current status of the incident. Valid values are: +"new","under_investigation","resolved_known_issue","resolved_duplicate","resolved_false_positive","resolved_true_positive","resolved_security_testing","resolved_other". | +| PaloAltoNetworksXDR.Incident.severity | String | Calculated severity of the incident. Valid values are: "low","medium","high". | +| PaloAltoNetworksXDR.Incident.description | String | Dynamic calculated description of the incident. | +| PaloAltoNetworksXDR.Incident.assigned_user_mail | String | Email address of the assigned user. | +| PaloAltoNetworksXDR.Incident.assigned_user_pretty_name | String | Full name of the user assigned to the incident. | +| PaloAltoNetworksXDR.Incident.alert_count | Number | Total number of alerts in the incident. | +| PaloAltoNetworksXDR.Incident.low_severity_alert_count | Number | Number of alerts with the severity LOW. | +| PaloAltoNetworksXDR.Incident.med_severity_alert_count | Number | Number of alerts with the severity MEDIUM. | +| PaloAltoNetworksXDR.Incident.high_severity_alert_count | Number | Number of alerts with the severity HIGH. | +| PaloAltoNetworksXDR.Incident.user_count | Number | Number of users involved in the incident. | +| PaloAltoNetworksXDR.Incident.host_count | Number | Number of hosts involved in the incident. | +| PaloAltoNetworksXDR.Incident.notes | Unknown | Comments entered by the user regarding the incident. | +| PaloAltoNetworksXDR.Incident.resolve_comment | String | Comments entered by the user when the incident was resolved. | +| PaloAltoNetworksXDR.Incident.manual_severity | String | Incident severity assigned by the user. This does not affect the calculated severity of low, medium, or high. | +| PaloAltoNetworksXDR.Incident.manual_description | String | Incident description provided by the user. | +| PaloAltoNetworksXDR.Incident.xdr_url | String | A link to the incident view on Cortex XDR. | +| PaloAltoNetworksXDR.Incident.starred | Boolean | Incident starred. | +| PaloAltoNetworksXDR.Incident.wildfire_hits.mitre_techniques_ids_and_names | String | Incident Mitre techniques IDs and names. | +| PaloAltoNetworksXDR.Incident.wildfire_hits.mitre_tactics_ids_and_names | String | Incident Mitre tactics ids and names. | +| PaloAltoNetworksXDR.Incident.alerts.alert_id | String | Unique ID for each alert. | +| PaloAltoNetworksXDR.Incident.alerts.detection_timestamp | Date | Date and time that the alert occurred. | +| PaloAltoNetworksXDR.Incident.alerts.source | String | Source of the alert. The product/vendor this alert came from. | +| PaloAltoNetworksXDR.Incident.alerts.severity | String | Severity of the alert.Valid values are: "low","medium","high""". | +| PaloAltoNetworksXDR.Incident.alerts.name | String | Calculated name of the alert. | +| PaloAltoNetworksXDR.Incident.alerts.category | String | Category of the alert, for example, Spyware Detected via Anti-Spyware profile. | +| PaloAltoNetworksXDR.Incident.alerts.description | String | Textual description of the alert. | +| PaloAltoNetworksXDR.Incident.alerts.host_ip_list | Unknown | Host IP involved in the alert. | +| PaloAltoNetworksXDR.Incident.alerts.host_name | String | Host name involved in the alert. | +| PaloAltoNetworksXDR.Incident.alerts.user_name | String | User name involved with the alert. | +| PaloAltoNetworksXDR.Incident.alerts.event_type | String | Event type. Valid values are: "Process Execution","Network Event","File Event","Registry Event","Injection Event","Load Image Event","Windows Event Log". | +| PaloAltoNetworksXDR.Incident.alerts.action | String | The action that triggered the alert. Valid values are: "REPORTED", "BLOCKED", "POST_DETECTED", "SCANNED", "DOWNLOAD", "PROMPT_ALLOW", "PROMPT_BLOCK", "DETECTED", "BLOCKED_1", "BLOCKED_2", "BLOCKED_3", "BLOCKED_5", "BLOCKED_6", "BLOCKED_7", "BLOCKED_8", "BLOCKED_9", "BLOCKED_10", "BLOCKED_11", "BLOCKED_13", "BLOCKED_14", "BLOCKED_15", "BLOCKED_16", "BLOCKED_17", "BLOCKED_24", "BLOCKED_25", "DETECTED_0", "DETECTED_4", "DETECTED_18", "DETECTED_19", "DETECTED_20", "DETECTED_21", "DETECTED_22", "DETECTED_23". | +| PaloAltoNetworksXDR.Incident.alerts.action_pretty | String | The action that triggered the alert. Valid values are: "Detected \(Reported\)" "Prevented \(Blocked\)" "Detected \(Post Detected\)" "Detected \(Scanned\)" "Detected \(Download\)" "Detected \(Prompt Allow\)" "Prevented \(Prompt Block\)" "Detected" "Prevented \(Denied The Session\)" "Prevented \(Dropped The Session\)" "Prevented \(Dropped The Session And Sent a TCP Reset\)" "Prevented \(Blocked The URL\)" "Prevented \(Blocked The IP\)" "Prevented \(Dropped The Packet\)" "Prevented \(Dropped All Packets\)" "Prevented \(Terminated The Session And Sent a TCP Reset To Both Sides Of The Connection\)" "Prevented \(Terminated The Session And Sent a TCP Reset To The Client\)" "Prevented \(Terminated The Session And Sent a TCP Reset To The Server\)" "Prevented \(Continue\)" "Prevented \(Block-Override\)" "Prevented \(Override-Lockout\)" "Prevented \(Override\)" "Prevented \(Random-Drop\)" "Prevented \(Silently Dropped The Session With An ICMP Unreachable Message To The Host Or Application\)" "Prevented \(Block\)" "Detected \(Allowed The Session\)" "Detected \(Raised An Alert\)" "Detected \(Syncookie Sent\)" "Detected \(Forward\)" "Detected \(Wildfire Upload Success\)" "Detected \(Wildfire Upload Failure\)" "Detected \(Wildfire Upload Skip\)" "Detected \(Sinkhole\)". | +| PaloAltoNetworksXDR.Incident.alerts.actor_process_image_name | String | Image name. | +| PaloAltoNetworksXDR.Incident.alerts.actor_process_command_line | String | Command line. | +| PaloAltoNetworksXDR.Incident.alerts.actor_process_signature_status | String | Signature status. Valid values are: "Signed" "Invalid Signature" "Unsigned" "Revoked" "Signature Fail" "N/A" "Weak Hash". | +| PaloAltoNetworksXDR.Incident.alerts.actor_process_signature_vendor | String | Signature vendor name. | +| PaloAltoNetworksXDR.Incident.alerts.causality_actor_process_image_name | String | Image name. | +| PaloAltoNetworksXDR.Incident.alerts.causality_actor_process_command_line | String | Command line. | +| PaloAltoNetworksXDR.Incident.alerts.causality_actor_process_signature_status | String | Signature status. Valid values are: "Signed" "Invalid Signature" "Unsigned" "Revoked" "Signature Fail" "N/A" "Weak Hash". | +| PaloAltoNetworksXDR.Incident.alerts.causality_actor_process_signature_vendor | String | Signature vendor. | +| PaloAltoNetworksXDR.Incident.alerts.causality_actor_causality_id | Unknown | Causality ID. | +| PaloAltoNetworksXDR.Incident.alerts.action_process_image_name | String | Image name. | +| PaloAltoNetworksXDR.Incident.alerts.action_process_image_command_line | String | Command line. | +| PaloAltoNetworksXDR.Incident.alerts.action_process_image_sha256 | String | Image SHA256. | +| PaloAltoNetworksXDR.Incident.alerts.action_process_signature_status | String | Signature status. Valid values are: "Signed" "Invalid Signature" "Unsigned" "Revoked" "Signature Fail" "N/A" "Weak Hash". | +| PaloAltoNetworksXDR.Incident.alerts.action_process_signature_vendor | String | Signature vendor name. | +| PaloAltoNetworksXDR.Incident.alerts.action_file_path | String | File path. | +| PaloAltoNetworksXDR.Incident.alerts.action_file_md5 | String | File MD5. | +| PaloAltoNetworksXDR.Incident.alerts.action_file_sha256 | String | File SHA256. | +| PaloAltoNetworksXDR.Incident.alerts.action_registry_data | String | Registry data. | +| PaloAltoNetworksXDR.Incident.alerts.action_registry_full_key | String | Registry full key. | +| PaloAltoNetworksXDR.Incident.alerts.action_local_ip | String | Local IP. | +| PaloAltoNetworksXDR.Incident.alerts.action_local_port | Number | Local port. | +| PaloAltoNetworksXDR.Incident.alerts.action_remote_ip | String | Remote IP. | +| PaloAltoNetworksXDR.Incident.alerts.action_remote_port | Number | Remote port. | +| PaloAltoNetworksXDR.Incident.alerts.action_external_hostname | String | External hostname. | +| PaloAltoNetworksXDR.Incident.alerts.fw_app_id | Unknown | Firewall app id. | +| PaloAltoNetworksXDR.Incident.alerts.is_whitelisted | String | Is the alert on allow list. Valid values are: "Yes" "No". | +| PaloAltoNetworksXDR.Incident.alerts.starred | Boolean | Alert starred. | +| PaloAltoNetworksXDR.Incident.network_artifacts.type | String | Network artifact type. | +| PaloAltoNetworksXDR.Incident.network_artifacts.network_remote_port | number | The remote port related to the artifact. | +| PaloAltoNetworksXDR.Incident.network_artifacts.alert_count | number | Number of alerts related to the artifact. | +| PaloAltoNetworksXDR.Incident.network_artifacts.network_remote_ip | String | The remote IP related to the artifact. | +| PaloAltoNetworksXDR.Incident.network_artifacts.is_manual | boolean | Whether the artifact was created by the user \(manually\). | +| PaloAltoNetworksXDR.Incident.network_artifacts.network_domain | String | The domain related to the artifact. | +| PaloAltoNetworksXDR.Incident.network_artifacts.type | String | The artifact type. Valid values are: "META", "GID", "CID", "HASH", "IP", "DOMAIN", "REGISTRY", "HOSTNAME". | +| PaloAltoNetworksXDR.Incident.network_artifacts.network_country | String | The country related to the artifact. | +| PaloAltoNetworksXDR.Incident.file_artifacts.file_signature_status | String | Digital signature status of the file. Valid values are: "SIGNATURE_UNAVAILABLE" "SIGNATURE_SIGNED" "SIGNATURE_INVALID" "SIGNATURE_UNSIGNED" "SIGNATURE_WEAK_HASH". | +| PaloAltoNetworksXDR.Incident.file_artifacts.is_process | boolean | Whether the file artifact is related to a process execution. | +| PaloAltoNetworksXDR.Incident.file_artifacts.file_name | String | Name of the file. | +| PaloAltoNetworksXDR.Incident.file_artifacts.file_wildfire_verdict | String | The file verdict, calculated by Wildfire. Valid values are: "BENIGN" "MALWARE" "GRAYWARE" "PHISHING" "UNKNOWN". | +| PaloAltoNetworksXDR.Incident.file_artifacts.alert_count | number | Number of alerts related to the artifact. | +| PaloAltoNetworksXDR.Incident.file_artifacts.is_malicious | boolean | Whether the artifact is malicious, as decided by the Wildfire verdict. | +| PaloAltoNetworksXDR.Incident.file_artifacts.is_manual | boolean | Whether the artifact was created by the user \(manually\). | +| PaloAltoNetworksXDR.Incident.file_artifacts.type | String | The artifact type. Valid values are: "META" "GID" "CID" "HASH" "IP" "DOMAIN" "REGISTRY" "HOSTNAME". | +| PaloAltoNetworksXDR.Incident.file_artifacts.file_sha256 | String | SHA256 hash of the file. | +| PaloAltoNetworksXDR.Incident.file_artifacts.file_signature_vendor_name | String | File signature vendor name. | +| Account.Username | String | The username in the relevant system. | +| Endpoint.Hostname | String | The hostname that is mapped to this endpoint. | +| File.Path | String | The path where the file is located. | +| File.MD5 | String | The MD5 hash of the file. | +| File.SHA256 | String | The SHA256 hash of the file. | +| File.Name | String | The full file name \(including file extension\). | +| Process.Name | String | The name of the process. | +| Process.MD5 | String | The MD5 hash of the process. | +| Process.SHA256 | String | The SHA256 hash of the process. | +| Process.PID | String | The PID of the process. | +| Process.Path | String | The file system path to the binary file. | +| Process.Start Time | String | The timestamp of the process start time. | +| Process.CommandLine | String | The full command line \(including arguments\). | +| IP.Address | String | IP address. | +| IP.Geo.Country | String | The country in which the IP address is located. | +| Domain.Name | String | The domain name, for example: "google.com". | + +### xdr-endpoint-isolate-ctf + +*** +Isolates the specified endpoint. + +#### Base Command + +`xdr-endpoint-isolate-ctf` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| incident_id | Allows linking the response action to the incident that triggered it. | Optional | +| endpoint_id | The endpoint ID (string) to isolate. You can retrieve the string from the xdr-get-endpoints command. | Required | +| suppress_disconnected_endpoint_error | Whether to suppress an error when trying to isolate a disconnected endpoint. When sets to false, an error will be returned. Possible values are: true, false. Default is false. | Optional | +| interval_in_seconds | Interval in seconds between each poll. | Optional | +| timeout_in_seconds | Polling timeout in seconds. | Optional | +| action_id | For polling use. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| PaloAltoNetworksXDR.Isolation.endpoint_id | String | The endpoint ID. | + +### xdr-file-retrieve-ctf + +*** +Retrieves files from selected endpoints. You can retrieve up to 20 files, from no more than 10 endpoints. At least one endpoint ID and one file path are necessary in order to run the command. After running this command, you can use the xdr-action-status-get command with returned action_id, to check the action status. + +#### Base Command + +`xdr-file-retrieve-ctf` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| endpoint_ids | A comma-separated list of endpoint IDs. | Required | +| generic_file_path | A comma-separated list of file paths in any platform. Can be used instead of the mac/windows/linux file paths. The order of the files path list must be parallel to the endpoints list order, so the first file path in the list is related to the first endpoint and so on. | Required | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| PaloAltoNetworksXDR.RetrievedFiles.action_id | string | ID of the action to retrieve files from selected endpoints. | +| PaloAltoNetworksXDR.RetrievedFiles.endpoint_id | string | Endpoint ID. Added only when the operation is successful. | +| PaloAltoNetworksXDR.RetrievedFiles.file_link | string | Link to the file. Added only when the operation is successful. | +| PaloAltoNetworksXDR.RetrievedFiles.status | string | The action status. Added only when the operation is unsuccessful. | + +### xdr-get-alerts-ctf + +*** +Returns a list of alerts and their metadata, which you can filter by built-in arguments or use the custom_filter to input a JSON filter object. +Multiple filter arguments will be concatenated using the AND operator, while arguments that support a comma-separated list of values will use an OR operator between each value. + +#### Base Command + +`xdr-get-alerts-ctf` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| alert_id | The unique ID of the alert. | Optional | +| severity | The severity of the alert. Possible values are: low, medium, high. | Optional | +| custom_filter | a custom filter, when using this argument, other filter arguments are not relevant. example:
    `{
    "OR": [
    {
    "SEARCH_FIELD": "actor_process_command_line",
    "SEARCH_TYPE": "EQ",
    "SEARCH_VALUE": "path_to_file"
    }
    ]
    }`. | Optional | +| Identity_type | Account type. Possible values are: ANONYMOUS, APPLICATION, COMPUTE, FEDERATED_IDENTITY, SERVICE, SERVICE_ACCOUNT, TEMPORARY_CREDENTIALS, TOKEN, UNKNOWN, USER. | Optional | +| agent_id | A unique identifier per agent. | Optional | +| action_external_hostname | The host name to connect to. In case of a proxy connection, this value will differ from action_remote_ip. | Optional | +| rule_id | A string identifying the user rule. | Optional | +| rule_name | The name of the user rule. | Optional | +| alert_name | The alert name. | Optional | +| alert_source | The alert source. | Optional | +| time_frame | Supports relative times or “custom” time option. If you choose the "custom" option, you should use start_time and end_time arguments. Possible values are: 60 minutes, 3 hours, 12 hours, 24 hours, 2 days, 7 days, 14 days, 30 days, custom. | Optional | +| user_name | The name assigned to the user_id during agent runtime. | Optional | +| actor_process_image_name | The file name of the binary file. | Optional | +| causality_actor_process_image_command_line | CGO CMD. | Optional | +| actor_process_image_command_line | Trimmed to 128 unicode chars during event serialization.
    Full value reported as part of the original process event. | Optional | +| action_process_image_command_line | The command line of the process created. | Optional | +| actor_process_image_sha256 | SHA256 of the binary file. | Optional | +| causality_actor_process_image_sha256 | SHA256 of the binary file. | Optional | +| action_process_image_sha256 | SHA256 of the binary file. | Optional | +| action_file_image_sha256 | SHA256 of the file related to the event. | Optional | +| action_registry_name | The name of the registry. | Optional | +| action_registry_key_data | The key data of the registry. | Optional | +| host_ip | The host IP. | Optional | +| action_local_ip | The local IP address for the connection. | Optional | +| action_remote_ip | Remote IP address for the connection. | Optional | +| alert_action_status | Alert action status. Possible values are: detected, detected (allowed the session), detected (download), detected (forward), detected (post detected), detected (prompt allow), detected (raised an alert), detected (reported), detected (on write), detected (scanned), detected (sinkhole), detected (syncookie sent), detected (wildfire upload failure), detected (wildfire upload success), detected (wildfire upload skip), detected (xdr managed threat hunting), prevented (block), prevented (blocked), prevented (block-override), prevented (blocked the url), prevented (blocked the ip), prevented (continue), prevented (denied the session), prevented (dropped all packets), prevented (dropped the session), prevented (dropped the session and sent a tcp reset), prevented (dropped the packet), prevented (override), prevented (override-lockout), prevented (post detected), prevented (prompt block), prevented (random-drop), prevented (silently dropped the session with an icmp unreachable message to the host or application), prevented (terminated the session and sent a tcp reset to both sides of the connection), prevented (terminated the session and sent a tcp reset to the client), prevented (terminated the session and sent a tcp reset to the server), prevented (on write). | Optional | +| action_local_port | The local IP address for the connection. | Optional | +| action_remote_port | The remote port for the connection. | Optional | +| dst_action_external_hostname | The hostname we connect to. In case of a proxy connection, this value will differ from action_remote_ip. | Optional | +| sort_field | The field by which we sort the results. Default is source_insert_ts. | Optional | +| sort_order | The order in which we sort the results. Possible values are: DESC, ASC. | Optional | +| offset | The first page from which we bring the alerts. Default is 0. | Optional | +| limit | The last page from which we bring the alerts. Default is 50. | Optional | +| start_time | Relevant when "time_frame" argument is "custom". Supports Epoch timestamp and simplified extended ISO format (YYYY-MM-DDThh:mm:ss.000Z). | Optional | +| end_time | Relevant when "time_frame" argument is "custom". Supports Epoch timestamp and simplified extended ISO format (YYYY-MM-DDThh:mm:ss.000Z). | Optional | +| starred | Whether the alert is starred or not. Possible values are: true, false. | Optional | +| mitre_technique_id_and_name | The MITRE attack technique. | Optional | + +#### Context Output + +| **Path** | **Type** | **Description** | +| --- | --- | --- | +| PaloAltoNetworksXDR.Alert.internal_id | String | The unique ID of the alert. | +| PaloAltoNetworksXDR.Alert.source_insert_ts | Number | The detection timestamp. | +| PaloAltoNetworksXDR.Alert.alert_name | String | The name of the alert. | +| PaloAltoNetworksXDR.Alert.severity | String | The severity of the alert. | +| PaloAltoNetworksXDR.Alert.alert_category | String | The category of the alert. | +| PaloAltoNetworksXDR.Alert.alert_action_status | String | The alert action. Possible values. + +DETECTED: detected +DETECTED_0: detected \(allowed the session\) +DOWNLOAD: detected \(download\) +DETECTED_19: detected \(forward\) +POST_DETECTED: detected \(post detected\) +PROMPT_ALLOW: detected \(prompt allow\) +DETECTED_4: detected \(raised an alert\) +REPORTED: detected \(reported\) +REPORTED_TRIGGER_4: detected \(on write\) +SCANNED: detected \(scanned\) +DETECTED_23: detected \(sinkhole\) +DETECTED_18: detected \(syncookie sent\) +DETECTED_21: detected \(wildfire upload failure\) +DETECTED_20: detected \(wildfire upload success\) +DETECTED_22: detected \(wildfire upload skip\) +DETECTED_MTH: detected \(xdr managed threat hunting\) +BLOCKED_25: prevented \(block\) +BLOCKED: prevented \(blocked\) +BLOCKED_14: prevented \(block-override\) +BLOCKED_5: prevented \(blocked the url\) +BLOCKED_6: prevented \(blocked the ip\) +BLOCKED_13: prevented \(continue\) +BLOCKED_1: prevented \(denied the session\) +BLOCKED_8: prevented \(dropped all packets\) +BLOCKED_2: prevented \(dropped the session\) +BLOCKED_3: prevented \(dropped the session and sent a tcp reset\) +BLOCKED_7: prevented \(dropped the packet\) +BLOCKED_16: prevented \(override\) +BLOCKED_15: prevented \(override-lockout\) +BLOCKED_26: prevented \(post detected\) +PROMPT_BLOCK: prevented \(prompt block\) +BLOCKED_17: prevented \(random-drop\) +BLOCKED_24: prevented \(silently dropped the session with an icmp unreachable message to the host or application\) +BLOCKED_9: prevented \(terminated the session and sent a tcp reset to both sides of the connection\) +BLOCKED_10: prevented \(terminated the session and sent a tcp reset to the client\) +BLOCKED_11: prevented \(terminated the session and sent a tcp reset to the server\) +BLOCKED_TRIGGER_4: prevented \(on write\). | +| PaloAltoNetworksXDR.Alert.alert_action_status_readable | String | The alert action. | +| PaloAltoNetworksXDR.Alert.alert_name | String | The alert name. | +| PaloAltoNetworksXDR.Alert.alert_description | String | The alert description. | +| PaloAltoNetworksXDR.Alert.agent_ip_addresses | String | The host IP. | +| PaloAltoNetworksXDR.Alert.agent_hostname | String | The host name. | +| PaloAltoNetworksXDR.Alert.mitre_tactic_id_and_name | String | The MITRE attack tactic. | +| PaloAltoNetworksXDR.Alert.mitre_technique_id_and_name | String | The MITRE attack technique. | +| PaloAltoNetworksXDR.Alert.starred | Boolean | Whether the alert is starred or not. | + diff --git a/Packs/ctf01/Integrations/OHMYVTCTF/OHMYVTCTF.yml b/Packs/ctf01/Integrations/OHMYVTCTF/OHMYVTCTF.yml index 1079436b6b99..79bbd1a95ad8 100644 --- a/Packs/ctf01/Integrations/OHMYVTCTF/OHMYVTCTF.yml +++ b/Packs/ctf01/Integrations/OHMYVTCTF/OHMYVTCTF.yml @@ -15,6 +15,7 @@ configuration: name: incidentType type: 13 - name: max_fetch + display: Max Fetch type: 0 defaultvalue: '50' - defaultvalue: 7 days @@ -26,7 +27,7 @@ configuration: script: script: '' type: python - dockerimage: demisto/python3:3.10.13.78960 + dockerimage: demisto/python3:3.10.13.87159 runonce: false subtype: python3 isfetch: true diff --git a/Packs/ctf01/Playbooks/playbook-Cortex_XDR_-_Possible_External_RDP_Brute-Force_CTF_README.md b/Packs/ctf01/Playbooks/playbook-Cortex_XDR_-_Possible_External_RDP_Brute-Force_CTF_README.md index 08076db296de..83244ae5d6e5 100644 --- a/Packs/ctf01/Playbooks/playbook-Cortex_XDR_-_Possible_External_RDP_Brute-Force_CTF_README.md +++ b/Packs/ctf01/Playbooks/playbook-Cortex_XDR_-_Possible_External_RDP_Brute-Force_CTF_README.md @@ -7,11 +7,11 @@ This playbook investigates a “Possible External RDP Brute Force” XDR Alert b - XDR Alert search - XDR Alerts that related to the same username and endpoint, and to the MITRE tactics that comes after "Credential Access", were found. Set verdict method: -* Critical Element - The "Critical Element" input allows you to select a specific element that, if identified as suspicious, the investigation's final verdict will be deemed a "True Positive". +- Critical Element - The "Critical Element" input allows you to select a specific element that, if identified as suspicious, the investigation's final verdict will be deemed a "True Positive". -* Final Verdict - Each suspicious element is being added to an array called "Suspicious Elements", which is used to count potential security threats. The array size will be compared to a final threshold. If the size is greater than or equal to the threshold, the investigation's final verdict will be deemed a "True Positive". +- Final Verdict - Each suspicious element is being added to an array called "Suspicious Elements", which is used to count potential security threats. The array size will be compared to a final threshold. If the size is greater than or equal to the threshold, the investigation's final verdict will be deemed a "True Positive". -* User Engagement - The "UserEngagementThreshold" input allows you to set the number of suspicious elements that trigger user engagement. When this threshold is met, an email will be sent to the user and their manager asking for authorization of RDP activity. If the RDP activity is not authorized by the user, the investigation's final verdict will be deemed a "True Positive". +- User Engagement - The "UserEngagementThreshold" input allows you to set the number of suspicious elements that trigger user engagement. When this threshold is met, an email will be sent to the user and their manager asking for authorization of RDP activity. If the RDP activity is not authorized by the user, the investigation's final verdict will be deemed a "True Positive". ## Dependencies @@ -20,25 +20,25 @@ This playbook uses the following sub-playbooks, integrations, and scripts. ### Sub-playbooks -* Cortex XDR - Get entity alerts by MITRE tactics CTF -* Threat Hunting - Generic -* TIM - Indicator Relationships Analysis -* Cortex XDR - Possible External RDP Brute-Force - Set Verdict -* Account Enrichment - Generic v2.1 +- Cortex XDR - Get entity alerts by MITRE tactics CTF +- Threat Hunting - Generic +- TIM - Indicator Relationships Analysis +- Cortex XDR - Possible External RDP Brute-Force - Set Verdict +- Account Enrichment - Generic v2.1 ### Integrations -* CortexXDRIRCTF -* OHMYVTCTF +- CortexXDRIRCTF +- OHMYVTCTF ### Scripts -* Set +- Set ### Commands -* setIncident -* ip +- setIncident +- ip ## Playbook Inputs diff --git a/Packs/ctf01/Playbooks/playbook-Cortex_XDR_Alerts_Handling_CTF_README.md b/Packs/ctf01/Playbooks/playbook-Cortex_XDR_Alerts_Handling_CTF_README.md index 2f62facc3298..c64a57ff6170 100644 --- a/Packs/ctf01/Playbooks/playbook-Cortex_XDR_Alerts_Handling_CTF_README.md +++ b/Packs/ctf01/Playbooks/playbook-Cortex_XDR_Alerts_Handling_CTF_README.md @@ -1,5 +1,6 @@ This playbook is used to loop over every alert in a Cortex XDR incident. Supported alert categories: + - Malware - Port Scan. @@ -9,16 +10,16 @@ This playbook uses the following sub-playbooks, integrations, and scripts. ### Sub-playbooks -* Cortex XDR - First SSO Access -* Cortex XDR - Cloud Cryptomining -* Cortex XDR - Port Scan - Adjusted -* Cortex XDR - Possible External RDP Brute-Force CTF -* GenericPolling -* Cortex XDR - Malware Investigation +- Cortex XDR - First SSO Access +- Cortex XDR - Cloud Cryptomining +- Cortex XDR - Port Scan - Adjusted +- Cortex XDR - Possible External RDP Brute-Force CTF +- GenericPolling +- Cortex XDR - Malware Investigation ### Integrations -* CortexXDRIRCTF +- CortexXDRIRCTF ### Scripts @@ -26,7 +27,7 @@ This playbook does not use any scripts. ### Commands -* xdr-get-incident-extra-data-ctf +- xdr-get-incident-extra-data-ctf ## Playbook Inputs diff --git a/Packs/ctf01/README.md b/Packs/ctf01/README.md index 9332b8f40fde..6c54c38fa277 100644 --- a/Packs/ctf01/README.md +++ b/Packs/ctf01/README.md @@ -4,6 +4,7 @@ This pack was prepared with small challenges which enables you to get familiar w To play this game, follow the instructions located within the "Prepare your CTF" playbook, that is part of this pack. For more information, visit the following references: + - [Prepare your instance for Capture The Flag](https://xsoar.pan.dev/docs/reference/packs/capture-the-flag-preparation) - [Introducing New XSOAR Capture the Flags!](https://www.paloaltonetworks.com/blog/security-operations/introducing-new-xsoar-capture-the-flags/) diff --git a/Packs/ctf01/ReleaseNotes/1_0_9.md b/Packs/ctf01/ReleaseNotes/1_0_9.md new file mode 100644 index 000000000000..b0cd4952b90f --- /dev/null +++ b/Packs/ctf01/ReleaseNotes/1_0_9.md @@ -0,0 +1,36 @@ + +#### Dashboards + +##### CTF 1 And 2 Dashboard + +- General maintenance. + +#### Integrations + +##### Cortex XDR - IR CTF + +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. + +##### Cortex XDR - IR CTF + +- General maintenance. + +##### OHMYVT_CTF +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. + +#### Mappers + +##### XDR - Incoming Mapper CTF + +- General maintenance. + +#### Reports + +##### Monthly Report for our CISO + +- General maintenance. + +#### Scripts + +##### CTF_1 +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. diff --git a/Packs/ctf01/Reports/report-Monthly_Report_for_our_CISO.json b/Packs/ctf01/Reports/report-Monthly_Report_for_our_CISO.json index 66a3cc511318..7932a06e2b26 100644 --- a/Packs/ctf01/Reports/report-Monthly_Report_for_our_CISO.json +++ b/Packs/ctf01/Reports/report-Monthly_Report_for_our_CISO.json @@ -1,7 +1,7 @@ { "cronView": false, "createdBy": "Dbot", - "tags": [], + "tags": [], "dashboard": { "fromDate": "0001-01-01T00:00:00Z", "fromDateLicense": "0001-01-01T00:00:00Z", diff --git a/Packs/ctf01/Scripts/CTF1/CTF1.yml b/Packs/ctf01/Scripts/CTF1/CTF1.yml index dd9903392bb1..7bcb6f12a5ea 100644 --- a/Packs/ctf01/Scripts/CTF1/CTF1.yml +++ b/Packs/ctf01/Scripts/CTF1/CTF1.yml @@ -23,7 +23,7 @@ args: scripttarget: 0 subtype: python3 runonce: false -dockerimage: demisto/python3:3.10.13.83255 +dockerimage: demisto/python3:3.10.13.87159 runas: DBotWeakRole engineinfo: {} fromversion: 8.2.0 diff --git a/Packs/ctf01/pack_metadata.json b/Packs/ctf01/pack_metadata.json index f0140116807c..99ec88b0e37e 100644 --- a/Packs/ctf01/pack_metadata.json +++ b/Packs/ctf01/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Capture The Flag - 01", "description": "XSOAR's Capture the flag (CTF)", "support": "xsoar", - "currentVersion": "1.0.8", + "currentVersion": "1.0.9", "serverMinVersion": "8.2.0", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", @@ -25,6 +25,7 @@ } }, "marketplaces": [ - "xsoar" + "xsoar", + "xsoar_saas" ] } \ No newline at end of file From 7537b2fdfee4d40ce5bdd37542c3e254c208003e Mon Sep 17 00:00:00 2001 From: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Date: Thu, 29 Feb 2024 14:01:29 +0200 Subject: [PATCH 111/272] [Microsoft API] generate_login_url - support prompt=consent (#31942) * added prompt=consent * update rn * Bump pack from version MicrosoftGraphFiles to 1.1.22. * update rn * update tests * update docker * Update Packs/MicrosoftGraphAPI/ReleaseNotes/1_1_39.md * updated docker * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * Bump pack from version MicrosoftDefenderAdvancedThreatProtection to 1.16.25. * Bump pack from version MicrosoftTeams to 1.4.47. * updated * updated * fixed * Bump pack from version AzureRiskyUsers to 1.1.30. * Bump pack from version AzureKeyVault to 1.1.39. * Bump pack from version AzureSQLManagement to 1.1.40. * Bump pack from version MicrosoftGraphApplications to 1.2.38. * Bump pack from version MicrosoftGraphGroups to 1.1.41. * Bump pack from version AzureDataExplorer to 1.2.36. * Bump pack from version MicrosoftGraphAPI to 1.1.40. * Bump pack from version AzureLogAnalytics to 1.1.25. * Bump pack from version MicrosoftGraphIdentityandAccess to 1.2.41. * Bump pack from version MicrosoftCloudAppSecurity to 2.1.54. * Bump pack from version MicrosoftManagementActivity to 1.3.37. * Bump pack from version AzureSentinel to 1.5.36. * Bump pack from version AzureFirewall to 1.1.35. * Bump pack from version AzureDevOps to 1.3.14. * Bump pack from version MicrosoftExchangeOnline to 1.2.38. * Bump pack from version MicrosoftCloudAppSecurity to 2.1.55. * fixed * Bump pack from version MicrosoftGraphDeviceManagement to 1.1.22. * Bump pack from version MicrosoftTeams to 1.4.48. * update rns * update docker * Apply suggestions from code review * Bump pack from version MicrosoftGraphDeviceManagement to 1.1.25. * Apply suggestions from code review update docker * Bump pack from version Microsoft365Defender to 4.5.18. * Bump pack from version Microsoft365Defender to 4.5.19. * Bump pack from version Microsoft365Defender to 4.5.20. * Bump pack from version MicrosoftGraphSecurity to 2.2.9. * add "Azure Kubernetes Services - Test" to "skipped_tests" * update docker * Bump pack from version MicrosoftTeams to 1.4.52. * Bump pack from version MicrosoftTeams to 1.4.53. * Bump pack from version MicrosoftExchangeOnline to 1.2.41. * Apply suggestions from code review * Bump pack from version MicrosoftGraphSecurity to 2.2.10. * Bump pack from version MicrosoftGraphSecurity to 2.2.11. * Bump pack from version AzureLogAnalytics to 1.1.28. --------- Co-authored-by: Content Bot Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- .../Scripts/MicrosoftApiModule/MicrosoftApiModule.py | 2 +- .../MicrosoftApiModule/MicrosoftApiModule_test.py | 2 +- Packs/AzureActiveDirectory/ReleaseNotes/1_3_20.md | 6 ++++++ Packs/AzureActiveDirectory/pack_metadata.json | 2 +- Packs/AzureCompute/ReleaseNotes/1_2_21.md | 6 ++++++ Packs/AzureCompute/pack_metadata.json | 2 +- .../AzureDataExplorer/AzureDataExplorer_test.py | 2 +- Packs/AzureDataExplorer/ReleaseNotes/1_2_38.md | 6 ++++++ Packs/AzureDataExplorer/pack_metadata.json | 2 +- .../Integrations/AzureDevOps/AzureDevOps_test.py | 2 +- Packs/AzureDevOps/ReleaseNotes/1_3_16.md | 6 ++++++ Packs/AzureDevOps/pack_metadata.json | 2 +- Packs/AzureFirewall/ReleaseNotes/1_1_37.md | 6 ++++++ Packs/AzureFirewall/pack_metadata.json | 2 +- Packs/AzureKeyVault/ReleaseNotes/1_1_41.md | 6 ++++++ Packs/AzureKeyVault/pack_metadata.json | 2 +- .../AzureKubernetesServices_test.py | 2 +- Packs/AzureKubernetesServices/ReleaseNotes/1_1_22.md | 6 ++++++ Packs/AzureKubernetesServices/pack_metadata.json | 2 +- .../AzureLogAnalytics/AzureLogAnalytics_test.py | 2 +- Packs/AzureLogAnalytics/ReleaseNotes/1_1_28.md | 6 ++++++ Packs/AzureLogAnalytics/pack_metadata.json | 2 +- .../AzureNetworkSecurityGroups_test.py | 2 +- .../AzureNetworkSecurityGroups/ReleaseNotes/1_2_24.md | 6 ++++++ Packs/AzureNetworkSecurityGroups/pack_metadata.json | 2 +- Packs/AzureRiskyUsers/ReleaseNotes/1_1_32.md | 6 ++++++ Packs/AzureRiskyUsers/pack_metadata.json | 2 +- .../AzureSQLManagement/AzureSQLManagement_test.py | 2 +- Packs/AzureSQLManagement/ReleaseNotes/1_1_42.md | 6 ++++++ Packs/AzureSQLManagement/pack_metadata.json | 2 +- Packs/AzureSecurityCenter/ReleaseNotes/2_0_22.md | 10 ++++++++++ Packs/AzureSecurityCenter/pack_metadata.json | 2 +- Packs/AzureSentinel/ReleaseNotes/1_5_38.md | 6 ++++++ Packs/AzureSentinel/pack_metadata.json | 4 ++-- .../Integrations/AzureStorage/AzureStorage_test.py | 2 +- Packs/AzureStorage/ReleaseNotes/1_2_22.md | 6 ++++++ Packs/AzureStorage/pack_metadata.json | 2 +- Packs/AzureWAF/Integrations/AzureWAF/AzureWAF_test.py | 2 +- Packs/AzureWAF/ReleaseNotes/1_1_20.md | 6 ++++++ Packs/AzureWAF/pack_metadata.json | 2 +- Packs/Microsoft365Defender/ReleaseNotes/4_5_20.md | 6 ++++++ Packs/Microsoft365Defender/pack_metadata.json | 2 +- .../MicrosoftCloudAppSecurity/ReleaseNotes/2_1_57.md | 10 ++++++++++ Packs/MicrosoftCloudAppSecurity/pack_metadata.json | 2 +- .../MicrosoftDefenderAdvancedThreatProtection_test.py | 2 +- .../ReleaseNotes/1_16_29.md | 10 ++++++++++ .../pack_metadata.json | 2 +- Packs/MicrosoftExchangeOnline/ReleaseNotes/1_2_41.md | 6 ++++++ Packs/MicrosoftExchangeOnline/pack_metadata.json | 2 +- Packs/MicrosoftGraphAPI/ReleaseNotes/1_1_43.md | 6 ++++++ Packs/MicrosoftGraphAPI/pack_metadata.json | 2 +- .../MicrosoftGraphApplications/ReleaseNotes/1_2_40.md | 6 ++++++ Packs/MicrosoftGraphApplications/pack_metadata.json | 2 +- Packs/MicrosoftGraphCalendar/ReleaseNotes/1_1_19.md | 6 ++++++ Packs/MicrosoftGraphCalendar/pack_metadata.json | 2 +- .../ReleaseNotes/1_1_25.md | 6 ++++++ .../MicrosoftGraphDeviceManagement/pack_metadata.json | 2 +- .../MicrosoftGraphFiles/MicrosoftGraphFiles_test.py | 2 +- Packs/MicrosoftGraphFiles/ReleaseNotes/1_1_23.md | 6 ++++++ Packs/MicrosoftGraphFiles/pack_metadata.json | 2 +- Packs/MicrosoftGraphGroups/ReleaseNotes/1_1_43.md | 6 ++++++ Packs/MicrosoftGraphGroups/pack_metadata.json | 2 +- .../ReleaseNotes/1_2_44.md | 6 ++++++ .../pack_metadata.json | 2 +- .../MicrosoftGraphListener_test.py | 2 +- Packs/MicrosoftGraphMail/ReleaseNotes/1_6_4.md | 10 ++++++++++ Packs/MicrosoftGraphMail/pack_metadata.json | 2 +- Packs/MicrosoftGraphSearch/ReleaseNotes/1_0_8.md | 6 ++++++ Packs/MicrosoftGraphSearch/pack_metadata.json | 2 +- Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_11.md | 6 ++++++ Packs/MicrosoftGraphSecurity/pack_metadata.json | 2 +- Packs/MicrosoftGraphTeams/ReleaseNotes/1_1_1.md | 6 ++++++ Packs/MicrosoftGraphTeams/pack_metadata.json | 2 +- .../MicrosoftGraphUser/MicrosoftGraphUser_test.py | 2 +- Packs/MicrosoftGraphUser/ReleaseNotes/1_5_30.md | 6 ++++++ Packs/MicrosoftGraphUser/pack_metadata.json | 2 +- .../MicrosoftManagementActivity_test.py | 2 +- .../ReleaseNotes/1_3_39.md | 6 ++++++ Packs/MicrosoftManagementActivity/pack_metadata.json | 2 +- .../Integrations/MicrosoftTeams/MicrosoftTeams.py | 2 +- .../Integrations/MicrosoftTeams/MicrosoftTeams.yml | 2 +- .../MicrosoftTeams/MicrosoftTeams_test.py | 2 +- Packs/MicrosoftTeams/ReleaseNotes/1_4_53.md | 11 +++++++++++ Packs/MicrosoftTeams/pack_metadata.json | 2 +- 84 files changed, 271 insertions(+), 52 deletions(-) create mode 100644 Packs/AzureActiveDirectory/ReleaseNotes/1_3_20.md create mode 100644 Packs/AzureCompute/ReleaseNotes/1_2_21.md create mode 100644 Packs/AzureDataExplorer/ReleaseNotes/1_2_38.md create mode 100644 Packs/AzureDevOps/ReleaseNotes/1_3_16.md create mode 100644 Packs/AzureFirewall/ReleaseNotes/1_1_37.md create mode 100644 Packs/AzureKeyVault/ReleaseNotes/1_1_41.md create mode 100644 Packs/AzureKubernetesServices/ReleaseNotes/1_1_22.md create mode 100644 Packs/AzureLogAnalytics/ReleaseNotes/1_1_28.md create mode 100644 Packs/AzureNetworkSecurityGroups/ReleaseNotes/1_2_24.md create mode 100644 Packs/AzureRiskyUsers/ReleaseNotes/1_1_32.md create mode 100644 Packs/AzureSQLManagement/ReleaseNotes/1_1_42.md create mode 100644 Packs/AzureSecurityCenter/ReleaseNotes/2_0_22.md create mode 100644 Packs/AzureSentinel/ReleaseNotes/1_5_38.md create mode 100644 Packs/AzureStorage/ReleaseNotes/1_2_22.md create mode 100644 Packs/AzureWAF/ReleaseNotes/1_1_20.md create mode 100644 Packs/Microsoft365Defender/ReleaseNotes/4_5_20.md create mode 100644 Packs/MicrosoftCloudAppSecurity/ReleaseNotes/2_1_57.md create mode 100644 Packs/MicrosoftDefenderAdvancedThreatProtection/ReleaseNotes/1_16_29.md create mode 100644 Packs/MicrosoftExchangeOnline/ReleaseNotes/1_2_41.md create mode 100644 Packs/MicrosoftGraphAPI/ReleaseNotes/1_1_43.md create mode 100644 Packs/MicrosoftGraphApplications/ReleaseNotes/1_2_40.md create mode 100644 Packs/MicrosoftGraphCalendar/ReleaseNotes/1_1_19.md create mode 100644 Packs/MicrosoftGraphDeviceManagement/ReleaseNotes/1_1_25.md create mode 100644 Packs/MicrosoftGraphFiles/ReleaseNotes/1_1_23.md create mode 100644 Packs/MicrosoftGraphGroups/ReleaseNotes/1_1_43.md create mode 100644 Packs/MicrosoftGraphIdentityandAccess/ReleaseNotes/1_2_44.md create mode 100644 Packs/MicrosoftGraphMail/ReleaseNotes/1_6_4.md create mode 100644 Packs/MicrosoftGraphSearch/ReleaseNotes/1_0_8.md create mode 100644 Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_11.md create mode 100644 Packs/MicrosoftGraphTeams/ReleaseNotes/1_1_1.md create mode 100644 Packs/MicrosoftGraphUser/ReleaseNotes/1_5_30.md create mode 100644 Packs/MicrosoftManagementActivity/ReleaseNotes/1_3_39.md create mode 100644 Packs/MicrosoftTeams/ReleaseNotes/1_4_53.md diff --git a/Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule.py b/Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule.py index fcabf902117d..6720c5ec2bd7 100644 --- a/Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule.py +++ b/Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule.py @@ -1496,7 +1496,7 @@ def generate_login_url(client: MicrosoftClient, login_url = urljoin(login_url, f'{client.tenant_id}/oauth2/v2.0/authorize?' f'response_type=code&scope=offline_access%20{client.scope.replace(" ", "%20")}' - f'&client_id={client.client_id}&redirect_uri={client.redirect_uri}') + f'&client_id={client.client_id}&redirect_uri={client.redirect_uri}&prompt=consent') result_msg = f"""### Authorization instructions 1. Click on the [login URL]({login_url}) to sign in and grant Cortex XSOAR permissions for your Azure Service Management. diff --git a/Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule_test.py b/Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule_test.py index 88420692c887..40c135e09e0b 100644 --- a/Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule_test.py +++ b/Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule_test.py @@ -724,7 +724,7 @@ def test_generate_login_url(): expected_url = f'[login URL](https://login.microsoftonline.com/{TENANT}/oauth2/v2.0/authorize?' \ f'response_type=code&scope=offline_access%20https://graph.microsoft.com/.default' \ - f'&client_id={CLIENT_ID}&redirect_uri=https://localhost/myapp)' + f'&client_id={CLIENT_ID}&redirect_uri=https://localhost/myapp&prompt=consent)' assert expected_url in result.readable_output, "Login URL is incorrect" diff --git a/Packs/AzureActiveDirectory/ReleaseNotes/1_3_20.md b/Packs/AzureActiveDirectory/ReleaseNotes/1_3_20.md new file mode 100644 index 000000000000..6a8e6f113435 --- /dev/null +++ b/Packs/AzureActiveDirectory/ReleaseNotes/1_3_20.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Active Directory Identity Protection (Deprecated) + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. diff --git a/Packs/AzureActiveDirectory/pack_metadata.json b/Packs/AzureActiveDirectory/pack_metadata.json index 10d83b1f29ee..108e2f286f6d 100644 --- a/Packs/AzureActiveDirectory/pack_metadata.json +++ b/Packs/AzureActiveDirectory/pack_metadata.json @@ -3,7 +3,7 @@ "description": "Deprecated. Use Microsoft Graph Identity and Access instead.", "support": "xsoar", "hidden": true, - "currentVersion": "1.3.19", + "currentVersion": "1.3.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureCompute/ReleaseNotes/1_2_21.md b/Packs/AzureCompute/ReleaseNotes/1_2_21.md new file mode 100644 index 000000000000..79697f8a76ee --- /dev/null +++ b/Packs/AzureCompute/ReleaseNotes/1_2_21.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Compute v2 + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/AzureCompute/pack_metadata.json b/Packs/AzureCompute/pack_metadata.json index 8ae62c4c94f9..094ac8ccf962 100644 --- a/Packs/AzureCompute/pack_metadata.json +++ b/Packs/AzureCompute/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Compute", "description": "Create and Manage Azure Virtual Machines", "support": "xsoar", - "currentVersion": "1.2.20", + "currentVersion": "1.2.21", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer_test.py b/Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer_test.py index f59019f3c77a..fd903e48f7f8 100644 --- a/Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer_test.py +++ b/Packs/AzureDataExplorer/Integrations/AzureDataExplorer/AzureDataExplorer_test.py @@ -321,6 +321,6 @@ def test_generate_login_url(mocker): expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ 'response_type=code' \ '&scope=offline_access%20https://management.azure.com/.default' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = AzureDataExplorer.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/AzureDataExplorer/ReleaseNotes/1_2_38.md b/Packs/AzureDataExplorer/ReleaseNotes/1_2_38.md new file mode 100644 index 000000000000..fa723040d26c --- /dev/null +++ b/Packs/AzureDataExplorer/ReleaseNotes/1_2_38.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Data Explorer + +Added support for the OAuth consent dialog after the user signs in using the ***azure-data-explorer-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/AzureDataExplorer/pack_metadata.json b/Packs/AzureDataExplorer/pack_metadata.json index aad0db744413..3ef2399d7743 100644 --- a/Packs/AzureDataExplorer/pack_metadata.json +++ b/Packs/AzureDataExplorer/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Data Explorer", "description": "Use Azure Data Explorer integration to collect and analyze data inside clusters of Azure Data Explorer and manage search queries.", "support": "xsoar", - "currentVersion": "1.2.37", + "currentVersion": "1.2.38", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps_test.py b/Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps_test.py index be5dc03b6ccb..7b4259f89c07 100644 --- a/Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps_test.py +++ b/Packs/AzureDevOps/Integrations/AzureDevOps/AzureDevOps_test.py @@ -822,7 +822,7 @@ def test_generate_login_url(mocker): expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ 'response_type=code' \ '&scope=offline_access%20499b84ac-1321-427f-aa17-267ca6975798/user_impersonation%20offline_access' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = AzureDevOps.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/AzureDevOps/ReleaseNotes/1_3_16.md b/Packs/AzureDevOps/ReleaseNotes/1_3_16.md new file mode 100644 index 000000000000..e2a6c2c6149f --- /dev/null +++ b/Packs/AzureDevOps/ReleaseNotes/1_3_16.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### AzureDevOps + +Added support for the OAuth consent dialog after the user signs in using the ***azure-devops-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/AzureDevOps/pack_metadata.json b/Packs/AzureDevOps/pack_metadata.json index daa7d537ea93..842f387656cf 100644 --- a/Packs/AzureDevOps/pack_metadata.json +++ b/Packs/AzureDevOps/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AzureDevOps", "description": "Create and manage Git repositories in Azure DevOps Services.", "support": "xsoar", - "currentVersion": "1.3.15", + "currentVersion": "1.3.16", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureFirewall/ReleaseNotes/1_1_37.md b/Packs/AzureFirewall/ReleaseNotes/1_1_37.md new file mode 100644 index 000000000000..61f666dcf71b --- /dev/null +++ b/Packs/AzureFirewall/ReleaseNotes/1_1_37.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Firewall + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/AzureFirewall/pack_metadata.json b/Packs/AzureFirewall/pack_metadata.json index 680885b187a4..e18ebe16838a 100644 --- a/Packs/AzureFirewall/pack_metadata.json +++ b/Packs/AzureFirewall/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Firewall", "description": "Azure Firewall is a cloud-native and intelligent network firewall security service that provides breed threat protection for cloud workloads running in Azure.It's a fully stateful, firewall as a service with built-in high availability and unrestricted cloud scalability.", "support": "xsoar", - "currentVersion": "1.1.36", + "currentVersion": "1.1.37", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureKeyVault/ReleaseNotes/1_1_41.md b/Packs/AzureKeyVault/ReleaseNotes/1_1_41.md new file mode 100644 index 000000000000..5ba68f3a3b6b --- /dev/null +++ b/Packs/AzureKeyVault/ReleaseNotes/1_1_41.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Key Vault + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/AzureKeyVault/pack_metadata.json b/Packs/AzureKeyVault/pack_metadata.json index 1407524961ff..e790d9250444 100644 --- a/Packs/AzureKeyVault/pack_metadata.json +++ b/Packs/AzureKeyVault/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Key Vault", "description": "Use Key Vault to safeguard and manage cryptographic keys and secrets used by cloud applications and services.", "support": "xsoar", - "currentVersion": "1.1.40", + "currentVersion": "1.1.41", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureKubernetesServices/Integrations/AzureKubernetesServices/AzureKubernetesServices_test.py b/Packs/AzureKubernetesServices/Integrations/AzureKubernetesServices/AzureKubernetesServices_test.py index 1345bf4077d3..d21bb6845694 100644 --- a/Packs/AzureKubernetesServices/Integrations/AzureKubernetesServices/AzureKubernetesServices_test.py +++ b/Packs/AzureKubernetesServices/Integrations/AzureKubernetesServices/AzureKubernetesServices_test.py @@ -193,6 +193,6 @@ def test_generate_login_url(mocker): # assert expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ 'response_type=code&scope=offline_access%20https://management.azure.com/.default' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = AzureKubernetesServices.return_results.call_args[0][0].readable_output assert expected_url in res, "Login URL is incorrect" diff --git a/Packs/AzureKubernetesServices/ReleaseNotes/1_1_22.md b/Packs/AzureKubernetesServices/ReleaseNotes/1_1_22.md new file mode 100644 index 000000000000..cf8c5ededee2 --- /dev/null +++ b/Packs/AzureKubernetesServices/ReleaseNotes/1_1_22.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Kubernetes Services + +Added support for the OAuth consent dialog after the user signs in using the ***azure-ks-generate-login-url*** command. diff --git a/Packs/AzureKubernetesServices/pack_metadata.json b/Packs/AzureKubernetesServices/pack_metadata.json index ac502176aef8..4e0ba724ab8e 100644 --- a/Packs/AzureKubernetesServices/pack_metadata.json +++ b/Packs/AzureKubernetesServices/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Kubernetes Services", "description": "Deploy and manage containerized applications with a fully managed Kubernetes service.", "support": "xsoar", - "currentVersion": "1.1.21", + "currentVersion": "1.1.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/AzureLogAnalytics_test.py b/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/AzureLogAnalytics_test.py index 3ba70e36f975..4749e216e742 100644 --- a/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/AzureLogAnalytics_test.py +++ b/Packs/AzureLogAnalytics/Integrations/AzureLogAnalytics/AzureLogAnalytics_test.py @@ -327,7 +327,7 @@ def test_generate_login_url(mocker: MockerFixture) -> None: f"[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?" "response_type=code&scope=offline_access%20https://api.loganalytics.io/Data.Read" "%20https://management.azure.com/user_impersonation" - f"&client_id={client_id}&redirect_uri={redirect_uri})" + f"&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)" ) res = AzureLogAnalytics.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/AzureLogAnalytics/ReleaseNotes/1_1_28.md b/Packs/AzureLogAnalytics/ReleaseNotes/1_1_28.md new file mode 100644 index 000000000000..f3c13897bcbc --- /dev/null +++ b/Packs/AzureLogAnalytics/ReleaseNotes/1_1_28.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Log Analytics + +Added support for the OAuth consent dialog after the user signs in using the ***azure-log-analytics-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/AzureLogAnalytics/pack_metadata.json b/Packs/AzureLogAnalytics/pack_metadata.json index 838236e50fa8..9867b484abb3 100644 --- a/Packs/AzureLogAnalytics/pack_metadata.json +++ b/Packs/AzureLogAnalytics/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Log Analytics", "description": "Log Analytics is a service that helps you collect and analyze data generated by resources in your cloud and on-premises environments.", "support": "xsoar", - "currentVersion": "1.1.27", + "currentVersion": "1.1.28", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureNetworkSecurityGroups/Integrations/AzureNetworkSecurityGroups/AzureNetworkSecurityGroups_test.py b/Packs/AzureNetworkSecurityGroups/Integrations/AzureNetworkSecurityGroups/AzureNetworkSecurityGroups_test.py index 99e3565eb76a..62aa4ee785d9 100644 --- a/Packs/AzureNetworkSecurityGroups/Integrations/AzureNetworkSecurityGroups/AzureNetworkSecurityGroups_test.py +++ b/Packs/AzureNetworkSecurityGroups/Integrations/AzureNetworkSecurityGroups/AzureNetworkSecurityGroups_test.py @@ -194,6 +194,6 @@ def test_generate_login_url(mocker): # assert expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ 'response_type=code&scope=offline_access%20https://management.azure.com/.default' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = AzureNetworkSecurityGroups.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/AzureNetworkSecurityGroups/ReleaseNotes/1_2_24.md b/Packs/AzureNetworkSecurityGroups/ReleaseNotes/1_2_24.md new file mode 100644 index 000000000000..4de929ef844b --- /dev/null +++ b/Packs/AzureNetworkSecurityGroups/ReleaseNotes/1_2_24.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Network Security Groups + +Added support for the OAuth consent dialog after the user signs in using the ***azure-nsg-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/AzureNetworkSecurityGroups/pack_metadata.json b/Packs/AzureNetworkSecurityGroups/pack_metadata.json index 00807e845399..d5fe672dc533 100644 --- a/Packs/AzureNetworkSecurityGroups/pack_metadata.json +++ b/Packs/AzureNetworkSecurityGroups/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Network Security Groups", "description": "Azure Network Security Groups are used to filter network traffic to and from Azure resources in an Azure virtual network", "support": "xsoar", - "currentVersion": "1.2.23", + "currentVersion": "1.2.24", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureRiskyUsers/ReleaseNotes/1_1_32.md b/Packs/AzureRiskyUsers/ReleaseNotes/1_1_32.md new file mode 100644 index 000000000000..f86c5225b969 --- /dev/null +++ b/Packs/AzureRiskyUsers/ReleaseNotes/1_1_32.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Risky Users + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/AzureRiskyUsers/pack_metadata.json b/Packs/AzureRiskyUsers/pack_metadata.json index 649e4f9ed79e..95a6a8d95ed0 100644 --- a/Packs/AzureRiskyUsers/pack_metadata.json +++ b/Packs/AzureRiskyUsers/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Risky Users", "description": "Azure Risky Users provides access to all at-risk users and risk detections in Azure AD environment.", "support": "xsoar", - "currentVersion": "1.1.31", + "currentVersion": "1.1.32", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureSQLManagement/Integrations/AzureSQLManagement/AzureSQLManagement_test.py b/Packs/AzureSQLManagement/Integrations/AzureSQLManagement/AzureSQLManagement_test.py index 68d199d43b3e..b6d1c9f9ac50 100644 --- a/Packs/AzureSQLManagement/Integrations/AzureSQLManagement/AzureSQLManagement_test.py +++ b/Packs/AzureSQLManagement/Integrations/AzureSQLManagement/AzureSQLManagement_test.py @@ -303,7 +303,7 @@ def test_generate_login_url(mocker): # assert expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ 'response_type=code&scope=offline_access%20https://management.azure.com/.default' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = AzureSQLManagement.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/AzureSQLManagement/ReleaseNotes/1_1_42.md b/Packs/AzureSQLManagement/ReleaseNotes/1_1_42.md new file mode 100644 index 000000000000..6669a258185e --- /dev/null +++ b/Packs/AzureSQLManagement/ReleaseNotes/1_1_42.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure SQL Management + +Added support for the OAuth consent dialog after the user signs in using the ***azure-sql-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/AzureSQLManagement/pack_metadata.json b/Packs/AzureSQLManagement/pack_metadata.json index a958282cbd01..7a8749af1c9c 100644 --- a/Packs/AzureSQLManagement/pack_metadata.json +++ b/Packs/AzureSQLManagement/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure SQL Management", "description": "Microsoft Azure SQL Database is a managed cloud database provided as part of Microsoft Azure", "support": "xsoar", - "currentVersion": "1.1.41", + "currentVersion": "1.1.42", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureSecurityCenter/ReleaseNotes/2_0_22.md b/Packs/AzureSecurityCenter/ReleaseNotes/2_0_22.md new file mode 100644 index 000000000000..cdf2cb17ad10 --- /dev/null +++ b/Packs/AzureSecurityCenter/ReleaseNotes/2_0_22.md @@ -0,0 +1,10 @@ + +#### Integrations + +##### Microsoft Defender for Cloud Event Collector + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. + +##### Microsoft Defender for Cloud + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. diff --git a/Packs/AzureSecurityCenter/pack_metadata.json b/Packs/AzureSecurityCenter/pack_metadata.json index e273913052d0..33b3b91b42e0 100644 --- a/Packs/AzureSecurityCenter/pack_metadata.json +++ b/Packs/AzureSecurityCenter/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Defender for Cloud", "description": "Unified security management and advanced threat protection across hybrid cloud workloads.", "support": "xsoar", - "currentVersion": "2.0.21", + "currentVersion": "2.0.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureSentinel/ReleaseNotes/1_5_38.md b/Packs/AzureSentinel/ReleaseNotes/1_5_38.md new file mode 100644 index 000000000000..178b6d77789f --- /dev/null +++ b/Packs/AzureSentinel/ReleaseNotes/1_5_38.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Sentinel + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/AzureSentinel/pack_metadata.json b/Packs/AzureSentinel/pack_metadata.json index 67990718e181..4e6629d38b87 100644 --- a/Packs/AzureSentinel/pack_metadata.json +++ b/Packs/AzureSentinel/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Sentinel", "description": "Microsoft Sentinel is a cloud-native security information and event manager (SIEM) platform that uses built-in AI to help analyze large volumes of data across an enterprise.", "support": "xsoar", - "currentVersion": "1.5.37", + "currentVersion": "1.5.38", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", @@ -17,4 +17,4 @@ "xsoar", "marketplacev2" ] -} +} \ No newline at end of file diff --git a/Packs/AzureStorage/Integrations/AzureStorage/AzureStorage_test.py b/Packs/AzureStorage/Integrations/AzureStorage/AzureStorage_test.py index e7f209e75f84..1e26a1ce6305 100644 --- a/Packs/AzureStorage/Integrations/AzureStorage/AzureStorage_test.py +++ b/Packs/AzureStorage/Integrations/AzureStorage/AzureStorage_test.py @@ -361,6 +361,6 @@ def test_generate_login_url(mocker): # assert expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ 'response_type=code&scope=offline_access%20https://management.azure.com/.default' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = AzureStorage.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/AzureStorage/ReleaseNotes/1_2_22.md b/Packs/AzureStorage/ReleaseNotes/1_2_22.md new file mode 100644 index 000000000000..e5b63160967f --- /dev/null +++ b/Packs/AzureStorage/ReleaseNotes/1_2_22.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Storage Management + +Added support for the OAuth consent dialog after the user signs in using the ***azure-storage-generate-login-url*** command. diff --git a/Packs/AzureStorage/pack_metadata.json b/Packs/AzureStorage/pack_metadata.json index f66afb41b02b..ac798986cdca 100644 --- a/Packs/AzureStorage/pack_metadata.json +++ b/Packs/AzureStorage/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure Storage Management", "description": "Deploy and manage storage accounts and blob service properties.", "support": "xsoar", - "currentVersion": "1.2.21", + "currentVersion": "1.2.22", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AzureWAF/Integrations/AzureWAF/AzureWAF_test.py b/Packs/AzureWAF/Integrations/AzureWAF/AzureWAF_test.py index ed1e04c25a77..8312ca8c0871 100644 --- a/Packs/AzureWAF/Integrations/AzureWAF/AzureWAF_test.py +++ b/Packs/AzureWAF/Integrations/AzureWAF/AzureWAF_test.py @@ -379,7 +379,7 @@ def test_generate_login_url(mocker): # assert expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ f'response_type=code&scope=offline_access%20{Scopes.management_azure}' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = AzureWAF.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/AzureWAF/ReleaseNotes/1_1_20.md b/Packs/AzureWAF/ReleaseNotes/1_1_20.md new file mode 100644 index 000000000000..acc261e43bca --- /dev/null +++ b/Packs/AzureWAF/ReleaseNotes/1_1_20.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Web Application Firewall + +Added support for the OAuth consent dialog after the user signs in using the ***azure-waf-generate-login-url*** command. diff --git a/Packs/AzureWAF/pack_metadata.json b/Packs/AzureWAF/pack_metadata.json index 5034fdc75310..708cf11bf36b 100644 --- a/Packs/AzureWAF/pack_metadata.json +++ b/Packs/AzureWAF/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Azure WAF", "description": "Azure Web Application Firewall is used to detect web related attacks targeting your web servers hosted in azure and allow quick respond to threats", "support": "xsoar", - "currentVersion": "1.1.19", + "currentVersion": "1.1.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Microsoft365Defender/ReleaseNotes/4_5_20.md b/Packs/Microsoft365Defender/ReleaseNotes/4_5_20.md new file mode 100644 index 000000000000..17ee673ce83e --- /dev/null +++ b/Packs/Microsoft365Defender/ReleaseNotes/4_5_20.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft 365 Defender + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/Microsoft365Defender/pack_metadata.json b/Packs/Microsoft365Defender/pack_metadata.json index 8589ef24ce1d..bc5f7b3acf64 100644 --- a/Packs/Microsoft365Defender/pack_metadata.json +++ b/Packs/Microsoft365Defender/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft 365 Defender", "description": "Microsoft 365 Defender is a unified pre- and post-breach enterprise defense suite that natively coordinates detection, prevention, investigation, and response across endpoints, identities, email, and applications to provide integrated protection against sophisticated attacks.", "support": "xsoar", - "currentVersion": "4.5.19", + "currentVersion": "4.5.20", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftCloudAppSecurity/ReleaseNotes/2_1_57.md b/Packs/MicrosoftCloudAppSecurity/ReleaseNotes/2_1_57.md new file mode 100644 index 000000000000..85fccbdc478d --- /dev/null +++ b/Packs/MicrosoftCloudAppSecurity/ReleaseNotes/2_1_57.md @@ -0,0 +1,10 @@ + +#### Integrations + +##### Microsoft Defender for Cloud Apps Event Collector + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. + +##### Microsoft Defender for Cloud Apps + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. diff --git a/Packs/MicrosoftCloudAppSecurity/pack_metadata.json b/Packs/MicrosoftCloudAppSecurity/pack_metadata.json index 2ada9cb4828b..4f9026eff9bf 100644 --- a/Packs/MicrosoftCloudAppSecurity/pack_metadata.json +++ b/Packs/MicrosoftCloudAppSecurity/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Defender for Cloud Apps", "description": "Microsoft Cloud App Security Integration, a Cloud Access Security Broker that supports various deployment modes", "support": "xsoar", - "currentVersion": "2.1.56", + "currentVersion": "2.1.57", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftDefenderAdvancedThreatProtection/Integrations/MicrosoftDefenderAdvancedThreatProtection/MicrosoftDefenderAdvancedThreatProtection_test.py b/Packs/MicrosoftDefenderAdvancedThreatProtection/Integrations/MicrosoftDefenderAdvancedThreatProtection/MicrosoftDefenderAdvancedThreatProtection_test.py index e0dd890ebe2e..259cfc8ba841 100644 --- a/Packs/MicrosoftDefenderAdvancedThreatProtection/Integrations/MicrosoftDefenderAdvancedThreatProtection/MicrosoftDefenderAdvancedThreatProtection_test.py +++ b/Packs/MicrosoftDefenderAdvancedThreatProtection/Integrations/MicrosoftDefenderAdvancedThreatProtection/MicrosoftDefenderAdvancedThreatProtection_test.py @@ -2892,6 +2892,6 @@ def test_generate_login_url(mocker): expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ f'response_type=code&scope=offline_access%20' \ 'https://securitycenter.onmicrosoft.com/windowsatpservice/.default' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = MicrosoftDefenderAdvancedThreatProtection.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/MicrosoftDefenderAdvancedThreatProtection/ReleaseNotes/1_16_29.md b/Packs/MicrosoftDefenderAdvancedThreatProtection/ReleaseNotes/1_16_29.md new file mode 100644 index 000000000000..eec5d438d015 --- /dev/null +++ b/Packs/MicrosoftDefenderAdvancedThreatProtection/ReleaseNotes/1_16_29.md @@ -0,0 +1,10 @@ + +#### Integrations + +##### Microsoft Defender for Endpoint Event Collector + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. + +##### Microsoft Defender for Endpoint + +Added support for the OAuth consent dialog after the user signs in using the ***microsoft-atp-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/MicrosoftDefenderAdvancedThreatProtection/pack_metadata.json b/Packs/MicrosoftDefenderAdvancedThreatProtection/pack_metadata.json index 8744b84e1483..b5e848cd11fb 100644 --- a/Packs/MicrosoftDefenderAdvancedThreatProtection/pack_metadata.json +++ b/Packs/MicrosoftDefenderAdvancedThreatProtection/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Defender for Endpoint", "description": "Microsoft Defender for Endpoint (previously Microsoft Defender Advanced Threat Protection (ATP)) is a unified platform for preventative protection, post-breach detection, automated investigation, and response.", "support": "xsoar", - "currentVersion": "1.16.28", + "currentVersion": "1.16.29", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftExchangeOnline/ReleaseNotes/1_2_41.md b/Packs/MicrosoftExchangeOnline/ReleaseNotes/1_2_41.md new file mode 100644 index 000000000000..0790bd637b5b --- /dev/null +++ b/Packs/MicrosoftExchangeOnline/ReleaseNotes/1_2_41.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### EWS O365 + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/MicrosoftExchangeOnline/pack_metadata.json b/Packs/MicrosoftExchangeOnline/pack_metadata.json index aa78201704bd..4a1951173423 100644 --- a/Packs/MicrosoftExchangeOnline/pack_metadata.json +++ b/Packs/MicrosoftExchangeOnline/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Exchange Online", "description": "Exchange Online and Office 365 (mail)", "support": "xsoar", - "currentVersion": "1.2.40", + "currentVersion": "1.2.41", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftGraphAPI/ReleaseNotes/1_1_43.md b/Packs/MicrosoftGraphAPI/ReleaseNotes/1_1_43.md new file mode 100644 index 000000000000..5a0a18b42f93 --- /dev/null +++ b/Packs/MicrosoftGraphAPI/ReleaseNotes/1_1_43.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Graph API + +Added support for the OAuth consent dialog after the user signs in using the ***msgraph-api-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/MicrosoftGraphAPI/pack_metadata.json b/Packs/MicrosoftGraphAPI/pack_metadata.json index 6712cc9e3353..04d47b89da1e 100644 --- a/Packs/MicrosoftGraphAPI/pack_metadata.json +++ b/Packs/MicrosoftGraphAPI/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph API", "description": "Use the Microsoft Graph API integration to interact with Microsoft APIs that do not have dedicated integrations in Cortex XSOAR, for example, Mail Single-User, etc.", "support": "xsoar", - "currentVersion": "1.1.42", + "currentVersion": "1.1.43", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftGraphApplications/ReleaseNotes/1_2_40.md b/Packs/MicrosoftGraphApplications/ReleaseNotes/1_2_40.md new file mode 100644 index 000000000000..2fecc11c0824 --- /dev/null +++ b/Packs/MicrosoftGraphApplications/ReleaseNotes/1_2_40.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Active Directory Applications + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/MicrosoftGraphApplications/pack_metadata.json b/Packs/MicrosoftGraphApplications/pack_metadata.json index 9e80191f4659..ca4255a10660 100644 --- a/Packs/MicrosoftGraphApplications/pack_metadata.json +++ b/Packs/MicrosoftGraphApplications/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Applications", "description": "Use this pack to manage connected applications and services", "support": "xsoar", - "currentVersion": "1.2.39", + "currentVersion": "1.2.40", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftGraphCalendar/ReleaseNotes/1_1_19.md b/Packs/MicrosoftGraphCalendar/ReleaseNotes/1_1_19.md new file mode 100644 index 000000000000..d4dd78f5e698 --- /dev/null +++ b/Packs/MicrosoftGraphCalendar/ReleaseNotes/1_1_19.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### O365 Outlook Calendar + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/MicrosoftGraphCalendar/pack_metadata.json b/Packs/MicrosoftGraphCalendar/pack_metadata.json index c584691d1bf9..56eb524d2d52 100644 --- a/Packs/MicrosoftGraphCalendar/pack_metadata.json +++ b/Packs/MicrosoftGraphCalendar/pack_metadata.json @@ -1,7 +1,7 @@ { "name": "Microsoft Graph Calendar", "description": "Microsoft Graph Calendar enables you to create and manage different calendars and events\n according to your requirements.", - "currentVersion": "1.1.18", + "currentVersion": "1.1.19", "support": "xsoar", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", diff --git a/Packs/MicrosoftGraphDeviceManagement/ReleaseNotes/1_1_25.md b/Packs/MicrosoftGraphDeviceManagement/ReleaseNotes/1_1_25.md new file mode 100644 index 000000000000..6a3ce5662e22 --- /dev/null +++ b/Packs/MicrosoftGraphDeviceManagement/ReleaseNotes/1_1_25.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Endpoint Manager (Intune) + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/MicrosoftGraphDeviceManagement/pack_metadata.json b/Packs/MicrosoftGraphDeviceManagement/pack_metadata.json index a7b511477f72..1964d507f390 100644 --- a/Packs/MicrosoftGraphDeviceManagement/pack_metadata.json +++ b/Packs/MicrosoftGraphDeviceManagement/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Device Management", "description": "Microsoft Graph Device Management", "support": "xsoar", - "currentVersion": "1.1.24", + "currentVersion": "1.1.25", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftGraphFiles/Integrations/MicrosoftGraphFiles/MicrosoftGraphFiles_test.py b/Packs/MicrosoftGraphFiles/Integrations/MicrosoftGraphFiles/MicrosoftGraphFiles_test.py index 86bcf0566c25..2d43b5508c98 100644 --- a/Packs/MicrosoftGraphFiles/Integrations/MicrosoftGraphFiles/MicrosoftGraphFiles_test.py +++ b/Packs/MicrosoftGraphFiles/Integrations/MicrosoftGraphFiles/MicrosoftGraphFiles_test.py @@ -934,7 +934,7 @@ def test_generate_login_url(mocker): main() expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ f'response_type=code&scope=offline_access%20{Scopes.graph}' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/MicrosoftGraphFiles/ReleaseNotes/1_1_23.md b/Packs/MicrosoftGraphFiles/ReleaseNotes/1_1_23.md new file mode 100644 index 000000000000..98861aaddc2a --- /dev/null +++ b/Packs/MicrosoftGraphFiles/ReleaseNotes/1_1_23.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### O365 File Management (Onedrive/Sharepoint/Teams) + +Added support for the OAuth consent dialog after the user signs in using the ***msgraph-files-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/MicrosoftGraphFiles/pack_metadata.json b/Packs/MicrosoftGraphFiles/pack_metadata.json index 5ecf16b09cb0..1cc5abff60c3 100644 --- a/Packs/MicrosoftGraphFiles/pack_metadata.json +++ b/Packs/MicrosoftGraphFiles/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Files", "description": "Use the O365 File Management (Onedrive/Sharepoint/Teams) integration to enable your app get authorized access to files in OneDrive, SharePoint, and MS Teams across your entire organization. This integration requires admin consent.", "support": "xsoar", - "currentVersion": "1.1.22", + "currentVersion": "1.1.23", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftGraphGroups/ReleaseNotes/1_1_43.md b/Packs/MicrosoftGraphGroups/ReleaseNotes/1_1_43.md new file mode 100644 index 000000000000..6debcc9e2be2 --- /dev/null +++ b/Packs/MicrosoftGraphGroups/ReleaseNotes/1_1_43.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Active Directory Groups + +Added support for the OAuth consent dialog after the user signs in using the ***msgraph-groups-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/MicrosoftGraphGroups/pack_metadata.json b/Packs/MicrosoftGraphGroups/pack_metadata.json index 8450165c7193..33cfc92c37c9 100644 --- a/Packs/MicrosoftGraphGroups/pack_metadata.json +++ b/Packs/MicrosoftGraphGroups/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Groups", "description": "Microsoft Graph Groups enables you to create and manage different types of groups and group functionality according to your requirements.", "support": "xsoar", - "currentVersion": "1.1.42", + "currentVersion": "1.1.43", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftGraphIdentityandAccess/ReleaseNotes/1_2_44.md b/Packs/MicrosoftGraphIdentityandAccess/ReleaseNotes/1_2_44.md new file mode 100644 index 000000000000..1dc138cf8289 --- /dev/null +++ b/Packs/MicrosoftGraphIdentityandAccess/ReleaseNotes/1_2_44.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Active Directory Identity And Access + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/MicrosoftGraphIdentityandAccess/pack_metadata.json b/Packs/MicrosoftGraphIdentityandAccess/pack_metadata.json index 03a18a8c20b5..687ec7095839 100644 --- a/Packs/MicrosoftGraphIdentityandAccess/pack_metadata.json +++ b/Packs/MicrosoftGraphIdentityandAccess/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Identity and Access", "description": "Use this pack to manage roles and members in Microsoft.", "support": "xsoar", - "currentVersion": "1.2.43", + "currentVersion": "1.2.44", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftGraphMail/Integrations/MicrosoftGraphListener/MicrosoftGraphListener_test.py b/Packs/MicrosoftGraphMail/Integrations/MicrosoftGraphListener/MicrosoftGraphListener_test.py index 3a81b5319448..3fd6b3066a67 100644 --- a/Packs/MicrosoftGraphMail/Integrations/MicrosoftGraphListener/MicrosoftGraphListener_test.py +++ b/Packs/MicrosoftGraphMail/Integrations/MicrosoftGraphListener/MicrosoftGraphListener_test.py @@ -1291,6 +1291,6 @@ def test_generate_login_url(mocker): # assert expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ f'response_type=code&scope=offline_access%20{Scopes.graph}' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = MicrosoftGraphListener.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/MicrosoftGraphMail/ReleaseNotes/1_6_4.md b/Packs/MicrosoftGraphMail/ReleaseNotes/1_6_4.md new file mode 100644 index 000000000000..af5e2344b457 --- /dev/null +++ b/Packs/MicrosoftGraphMail/ReleaseNotes/1_6_4.md @@ -0,0 +1,10 @@ + +#### Integrations + +##### O365 Outlook Mail (Using Graph API) + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. + +##### Microsoft Graph Mail Single User + +Added support for the OAuth consent dialog after the user signs in using the ***msgraph-mail-generate-login-url*** command. diff --git a/Packs/MicrosoftGraphMail/pack_metadata.json b/Packs/MicrosoftGraphMail/pack_metadata.json index 34c3c8de8611..5af0198ebb42 100644 --- a/Packs/MicrosoftGraphMail/pack_metadata.json +++ b/Packs/MicrosoftGraphMail/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Mail", "description": "Microsoft Graph lets your app get authorized access to a user's Outlook mail data in a personal or organization account.", "support": "xsoar", - "currentVersion": "1.6.3", + "currentVersion": "1.6.4", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftGraphSearch/ReleaseNotes/1_0_8.md b/Packs/MicrosoftGraphSearch/ReleaseNotes/1_0_8.md new file mode 100644 index 000000000000..e0467de1b253 --- /dev/null +++ b/Packs/MicrosoftGraphSearch/ReleaseNotes/1_0_8.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Graph Search + +Added support for the OAuth consent dialog after the user signs in using the ***msgraph-search-generate-login-url*** command. diff --git a/Packs/MicrosoftGraphSearch/pack_metadata.json b/Packs/MicrosoftGraphSearch/pack_metadata.json index d48dbcb2d4b5..4b1a50a03a19 100644 --- a/Packs/MicrosoftGraphSearch/pack_metadata.json +++ b/Packs/MicrosoftGraphSearch/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Search", "description": "Use the Microsoft Search API in Microsoft Graph to search content stored in OneDrive or SharePoint: files, folders, lists, list items, or sites.", "support": "community", - "currentVersion": "1.0.7", + "currentVersion": "1.0.8", "author": "randomizerxd", "url": "", "email": "", diff --git a/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_11.md b/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_11.md new file mode 100644 index 000000000000..a332bae14254 --- /dev/null +++ b/Packs/MicrosoftGraphSecurity/ReleaseNotes/2_2_11.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Graph Security + +Added support for the OAuth consent dialog after the user signs in using the ***msg-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/MicrosoftGraphSecurity/pack_metadata.json b/Packs/MicrosoftGraphSecurity/pack_metadata.json index 3075994a1060..7b48371b42d0 100644 --- a/Packs/MicrosoftGraphSecurity/pack_metadata.json +++ b/Packs/MicrosoftGraphSecurity/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph Security", "description": "Unified gateway to security insights - all from a unified Microsoft Graph\n Security API.", "support": "xsoar", - "currentVersion": "2.2.10", + "currentVersion": "2.2.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftGraphTeams/ReleaseNotes/1_1_1.md b/Packs/MicrosoftGraphTeams/ReleaseNotes/1_1_1.md new file mode 100644 index 000000000000..05b8eab233cf --- /dev/null +++ b/Packs/MicrosoftGraphTeams/ReleaseNotes/1_1_1.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### O365 Teams (Using Graph API) + +Added support for the OAuth consent dialog after the user signs in using the ***msgraph-teams-generate-login-url*** command. diff --git a/Packs/MicrosoftGraphTeams/pack_metadata.json b/Packs/MicrosoftGraphTeams/pack_metadata.json index 3303cf0a4bba..fd7e069590dd 100644 --- a/Packs/MicrosoftGraphTeams/pack_metadata.json +++ b/Packs/MicrosoftGraphTeams/pack_metadata.json @@ -2,7 +2,7 @@ "name": "MicrosoftGraphTeams", "description": "O365 Teams (Using Graph API) gives you authorized access to a user’s Teams enabling you to facilitate communication through teams as that user, or read conversations and/or messages of that user.", "support": "community", - "currentVersion": "1.1.0", + "currentVersion": "1.1.1", "author": "Joachim Bockland", "url": "", "email": "", diff --git a/Packs/MicrosoftGraphUser/Integrations/MicrosoftGraphUser/MicrosoftGraphUser_test.py b/Packs/MicrosoftGraphUser/Integrations/MicrosoftGraphUser/MicrosoftGraphUser_test.py index cea86855f5aa..73eadac0d7a3 100644 --- a/Packs/MicrosoftGraphUser/Integrations/MicrosoftGraphUser/MicrosoftGraphUser_test.py +++ b/Packs/MicrosoftGraphUser/Integrations/MicrosoftGraphUser/MicrosoftGraphUser_test.py @@ -341,7 +341,7 @@ def test_generate_login_url(mocker): # assert expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ f'response_type=code&scope=offline_access%20{Scopes.graph}' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = MicrosoftGraphUser.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/MicrosoftGraphUser/ReleaseNotes/1_5_30.md b/Packs/MicrosoftGraphUser/ReleaseNotes/1_5_30.md new file mode 100644 index 000000000000..3b2e0d2b5a1e --- /dev/null +++ b/Packs/MicrosoftGraphUser/ReleaseNotes/1_5_30.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Azure Active Directory Users + +Added support for the OAuth consent dialog after the user signs in using the ***msgraph-user-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/MicrosoftGraphUser/pack_metadata.json b/Packs/MicrosoftGraphUser/pack_metadata.json index ae2fcd9f8e8a..3a7f6dacad9c 100644 --- a/Packs/MicrosoftGraphUser/pack_metadata.json +++ b/Packs/MicrosoftGraphUser/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Graph User", "description": "Use the Microsoft Graph integration to connect to and interact with user objects on Microsoft Platforms.", "support": "xsoar", - "currentVersion": "1.5.29", + "currentVersion": "1.5.30", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftManagementActivity/Integrations/MicrosoftManagementActivity/MicrosoftManagementActivity_test.py b/Packs/MicrosoftManagementActivity/Integrations/MicrosoftManagementActivity/MicrosoftManagementActivity_test.py index 609e5bf323a0..e6d216845304 100644 --- a/Packs/MicrosoftManagementActivity/Integrations/MicrosoftManagementActivity/MicrosoftManagementActivity_test.py +++ b/Packs/MicrosoftManagementActivity/Integrations/MicrosoftManagementActivity/MicrosoftManagementActivity_test.py @@ -733,7 +733,7 @@ def test_generate_login_url(mocker): # assert expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ 'response_type=code&scope=offline_access%20https://management.azure.com/.default' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = MicrosoftManagementActivity.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/MicrosoftManagementActivity/ReleaseNotes/1_3_39.md b/Packs/MicrosoftManagementActivity/ReleaseNotes/1_3_39.md new file mode 100644 index 000000000000..f6a0c50fb83a --- /dev/null +++ b/Packs/MicrosoftManagementActivity/ReleaseNotes/1_3_39.md @@ -0,0 +1,6 @@ + +#### Integrations + +##### Microsoft Management Activity API (O365 Azure Events) + +Added support for the OAuth consent dialog after the user signs in using the ***ms-management-activity-generate-login-url*** command. \ No newline at end of file diff --git a/Packs/MicrosoftManagementActivity/pack_metadata.json b/Packs/MicrosoftManagementActivity/pack_metadata.json index f7a9906aacf3..a1eac0f0521e 100644 --- a/Packs/MicrosoftManagementActivity/pack_metadata.json +++ b/Packs/MicrosoftManagementActivity/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Management Activity API (O365/Azure Events)", "description": "An integration for Microsoft's management activity API, which enables you to fetch content records and manage your subscriptions.", "support": "xsoar", - "currentVersion": "1.3.38", + "currentVersion": "1.3.39", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams.py b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams.py index e4e3a1483341..0316be17ce12 100644 --- a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams.py +++ b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams.py @@ -2744,7 +2744,7 @@ def test_module(): def generate_login_url_command(): login_url = f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/authorize?' \ f'response_type=code&scope=offline_access%20https://graph.microsoft.com/.default' \ - f'&client_id={BOT_ID}&redirect_uri={REDIRECT_URI}' + f'&client_id={BOT_ID}&redirect_uri={REDIRECT_URI}&prompt=consent' result_msg = f"""### Authorization instructions 1. Click on the [login URL]({login_url}) to sign in and grant Cortex XSOAR permissions for your Azure Service Management. diff --git a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams.yml b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams.yml index 3ed5b29a5b2e..1d35075f5bcc 100644 --- a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams.yml +++ b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams.yml @@ -712,7 +712,7 @@ script: - description: Generate the login url used for Authorization code flow. name: microsoft-teams-generate-login-url arguments: [] - dockerimage: demisto/teams:1.0.0.86933 + dockerimage: demisto/teams:1.0.0.88121 longRunning: true longRunningPort: true script: '' diff --git a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams_test.py b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams_test.py index 21d8c3fc1e65..c016c125f798 100644 --- a/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams_test.py +++ b/Packs/MicrosoftTeams/Integrations/MicrosoftTeams/MicrosoftTeams_test.py @@ -2276,7 +2276,7 @@ def test_generate_login_url(mocker): # assert expected_url = f'[login URL](https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?' \ 'response_type=code&scope=offline_access%20https://graph.microsoft.com/.default' \ - f'&client_id={client_id}&redirect_uri={redirect_uri})' + f'&client_id={client_id}&redirect_uri={redirect_uri}&prompt=consent)' res = MicrosoftTeams.return_results.call_args[0][0].readable_output assert expected_url in res diff --git a/Packs/MicrosoftTeams/ReleaseNotes/1_4_53.md b/Packs/MicrosoftTeams/ReleaseNotes/1_4_53.md new file mode 100644 index 000000000000..64536b1e3171 --- /dev/null +++ b/Packs/MicrosoftTeams/ReleaseNotes/1_4_53.md @@ -0,0 +1,11 @@ + +#### Integrations + +##### Microsoft Teams + +- Added support for the OAuth consent dialog after the user signs in using the ***microsoft-teams-generate-login-url*** command. +- Updated the Docker image to: *demisto/teams:1.0.0.88121*. + +##### Microsoft Teams Management + +Updated the **MicrosoftApiModule** to better handle the Authorization Code flow in the supported integrations. \ No newline at end of file diff --git a/Packs/MicrosoftTeams/pack_metadata.json b/Packs/MicrosoftTeams/pack_metadata.json index 287d1fc63d90..d40dc0a2db3f 100644 --- a/Packs/MicrosoftTeams/pack_metadata.json +++ b/Packs/MicrosoftTeams/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Microsoft Teams", "description": "Send messages and notifications to your team members.", "support": "xsoar", - "currentVersion": "1.4.52", + "currentVersion": "1.4.53", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 05b5281e3763d83d57a8383eb1db0ea3b19d1f70 Mon Sep 17 00:00:00 2001 From: Dan Sterenson <38375556+dansterenson@users.noreply.github.com> Date: Thu, 29 Feb 2024 16:07:33 +0200 Subject: [PATCH 112/272] Slack war room url fix (#33113) * fix war room url * Add UT * Added RN * lint fix * Cr fixes --- Packs/Slack/Integrations/SlackV3/SlackV3.py | 21 +++++++++++++++ Packs/Slack/Integrations/SlackV3/SlackV3.yml | 2 +- .../Integrations/SlackV3/SlackV3_test.py | 26 +++++++++++++++++++ Packs/Slack/ReleaseNotes/3_4_7.md | 7 +++++ Packs/Slack/pack_metadata.json | 2 +- 5 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 Packs/Slack/ReleaseNotes/3_4_7.md diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3.py b/Packs/Slack/Integrations/SlackV3/SlackV3.py index bd0a3318dd78..e6c277184f2d 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3.py +++ b/Packs/Slack/Integrations/SlackV3/SlackV3.py @@ -8,6 +8,8 @@ from distutils.util import strtobool import aiohttp import slack_sdk +from urllib.parse import urlparse + from slack_sdk.errors import SlackApiError from slack_sdk.socket_mode.aiohttp import SocketModeClient from slack_sdk.socket_mode.request import SocketModeRequest @@ -95,6 +97,24 @@ ''' HELPER FUNCTIONS ''' +def get_war_room_url(url: str) -> str: + # a workaround until this bug is resolved: https://jira-dc.paloaltonetworks.com/browse/CRTX-107526 + if is_xsiam(): + incident_id = demisto.callingContext.get('context', {}).get('Inv', {}).get('id') + incident_url = urlparse(url) + war_room_url = f"{incident_url.scheme}://{incident_url.netloc}/incidents" + # executed from the incident War Room + if incident_id and incident_id.startswith('INCIDENT-'): + war_room_url += f"/war_room?caseId={incident_id.split('-')[-1]}" + # executed from the alert War Room + else: + war_room_url += f"/alerts_and_insights?caseId={incident_id}&action:openAlertDetails={incident_id}-warRoom" + + return war_room_url + + return url + + def get_bot_id() -> str: """ Gets the app bot ID @@ -2034,6 +2054,7 @@ def send_message(destinations: list, entry: str, ignore_add_url: bool, integrati if investigation.get('type') != PLAYGROUND_INVESTIGATION_TYPE: link = server_links.get('warRoom') if link: + link = get_war_room_url(link) if entry: link += '/' + entry message += f'\nView it on: {link}' diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3.yml b/Packs/Slack/Integrations/SlackV3/SlackV3.yml index 409d2532aaca..2b57eba1b47b 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3.yml +++ b/Packs/Slack/Integrations/SlackV3/SlackV3.yml @@ -498,7 +498,7 @@ script: description: Set this argument to specify how many results to return. description: Retrieves replies to specific messages, regardless of whether it's from a public or private channel, direct message, or otherwise. name: slack-get-conversation-replies - dockerimage: demisto/slackv3:1.0.0.87650 + dockerimage: demisto/slackv3:1.0.0.88538 longRunning: true runonce: false script: '-' diff --git a/Packs/Slack/Integrations/SlackV3/SlackV3_test.py b/Packs/Slack/Integrations/SlackV3/SlackV3_test.py index 5554b9457304..9ccad211b8be 100644 --- a/Packs/Slack/Integrations/SlackV3/SlackV3_test.py +++ b/Packs/Slack/Integrations/SlackV3/SlackV3_test.py @@ -8,6 +8,7 @@ from slack_sdk.errors import SlackApiError from slack_sdk.web.async_slack_response import AsyncSlackResponse from slack_sdk.web.slack_response import SlackResponse +from SlackV3 import get_war_room_url from CommonServerPython import * @@ -5178,3 +5179,28 @@ async def test_listen(client_session): assert result_incident_id == '3' assert result_entitlement == '326a8a51-3dbd-4b07-8662-d36bfa9509fb' assert test_result_content == expected_content + + +class TestGetWarRoomURL: + + def test_get_war_room_url_with_xsiam_from_incident_war_room(self, mocker): + url = "https://example.com/WarRoom/INCIDENT-2930" + expected_war_room_url = "https://example.com/incidents/war_room?caseId=2930" + mocker.patch('SlackV3.is_xsiam', return_value=True) + mocker.patch.dict(demisto.callingContext, {'context': {'Inv': {'id': 'INCIDENT-2930'}}}) + + assert get_war_room_url(url) == expected_war_room_url + + def test_get_war_room_url_without_xsiam_from_incident_war_room(self, mocker): + url = "https://example.com/WarRoom/INCIDENT-2930" + mocker.patch('SlackV3.is_xsiam', return_value=False) + expected_war_room_url = "https://example.com/WarRoom/INCIDENT-2930" + assert get_war_room_url(url) == expected_war_room_url + + def test_get_war_room_url_with_xsiam_from_alert_war_room(self, mocker): + url = "https://example.com/WarRoom/ALERT-1234" + mocker.patch('SlackV3.is_xsiam', return_value=True) + mocker.patch.dict(demisto.callingContext, {'context': {'Inv': {'id': '1234'}}}) + expected_war_room_url = \ + "https://example.com/incidents/alerts_and_insights?caseId=1234&action:openAlertDetails=1234-warRoom" + assert get_war_room_url(url) == expected_war_room_url diff --git a/Packs/Slack/ReleaseNotes/3_4_7.md b/Packs/Slack/ReleaseNotes/3_4_7.md new file mode 100644 index 000000000000..5b1b479e222e --- /dev/null +++ b/Packs/Slack/ReleaseNotes/3_4_7.md @@ -0,0 +1,7 @@ + +#### Integrations + +##### Slack v3 + +- Fixed an issue where the ***send-notification*** command did not send the correct URL on Slack message. +- Updated the Docker image to: *demisto/slackv3:1.0.0.88538*. diff --git a/Packs/Slack/pack_metadata.json b/Packs/Slack/pack_metadata.json index 29638ec27709..c5450a8cd118 100644 --- a/Packs/Slack/pack_metadata.json +++ b/Packs/Slack/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Slack", "description": "Interact with Slack API - collect logs, send messages and notifications to your Slack team.", "support": "xsoar", - "currentVersion": "3.4.6", + "currentVersion": "3.4.7", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From d01e1d5b75ea687763e9ef18ff24c466e0e34be5 Mon Sep 17 00:00:00 2001 From: Dan Sterenson <38375556+dansterenson@users.noreply.github.com> Date: Thu, 29 Feb 2024 16:29:33 +0200 Subject: [PATCH 113/272] Assign analyst to incident error on incident (#33078) * Added script and mapping * converting playbook scripts * Add system fields * added an informative error if script was used from an incident war-room on XSIAM * remove unwanted files * add RN * add RN * Bump pack from version CommonScripts to 1.14.3. * add comma to end of arg * Cr fixes --------- Co-authored-by: Content Bot --- Packs/CommonScripts/ReleaseNotes/1_14_3.md | 8 ++++++++ .../AssignAnalystToIncident.js | 18 ++++++++++++++++++ .../AssignAnalystToIncident.yml | 15 +++++++++++++-- Packs/CommonScripts/pack_metadata.json | 2 +- 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 Packs/CommonScripts/ReleaseNotes/1_14_3.md diff --git a/Packs/CommonScripts/ReleaseNotes/1_14_3.md b/Packs/CommonScripts/ReleaseNotes/1_14_3.md new file mode 100644 index 000000000000..4f27bf5381f0 --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_14_3.md @@ -0,0 +1,8 @@ + +#### Scripts + +##### AssignAnalystToIncident + +<~XSIAM> +Fixed an issue where the script was not displaying an error when executed from the incident war room. + \ No newline at end of file diff --git a/Packs/CommonScripts/Scripts/AssignAnalystToIncident/AssignAnalystToIncident.js b/Packs/CommonScripts/Scripts/AssignAnalystToIncident/AssignAnalystToIncident.js index 383fd69184a7..4887f8ad18fd 100644 --- a/Packs/CommonScripts/Scripts/AssignAnalystToIncident/AssignAnalystToIncident.js +++ b/Packs/CommonScripts/Scripts/AssignAnalystToIncident/AssignAnalystToIncident.js @@ -1,3 +1,21 @@ +// returns true if the current platform is XSIAM. +isXsiam = function () { + res = getDemistoVersion(); + platform = res.platform; + if (platform === "x2") { + return true + } + return false +} + +if (isXsiam()){ + incidentObject = JSON.parse(incObj); + if (incidentObject.length > 0 && incidentObject[0].id.startsWith("INCIDENT")) { + throw "AssignAnalystToIncident script can only be used within an alert and not from an incident." + } +} + + if (args.email && args.username) { throw 'Please provide either username or email'; } diff --git a/Packs/CommonScripts/Scripts/AssignAnalystToIncident/AssignAnalystToIncident.yml b/Packs/CommonScripts/Scripts/AssignAnalystToIncident/AssignAnalystToIncident.yml index bf8ddb936e92..bdd1204502f6 100644 --- a/Packs/CommonScripts/Scripts/AssignAnalystToIncident/AssignAnalystToIncident.yml +++ b/Packs/CommonScripts/Scripts/AssignAnalystToIncident/AssignAnalystToIncident.yml @@ -14,7 +14,18 @@ comment: |- top-user: The user that is most commonly owns this type of incident less-busy-user: The less busy analyst will be picked to be the incident owner. online: The analyst is picked randomly from all online analysts, according to the provided roles (if no roles provided, will fetch all users). - current: The user that executed the command + current: The user that executed the command. +comment:marketplacev2: |- + Assign analyst to incident. + Note: the script should be executed from within an alert. + By default, the analyst is picked randomly from the available users, according to the provided roles (if no roles provided, will fetch all users). + Otherwise, the analyst will be picked according to the 'assignBy' arguments. + machine-learning: DBot will calculated and decide who is the best analyst for the job. + top-user: The user that is most commonly owns this type of incident + less-busy-user: The less busy analyst will be picked to be the incident owner. + online: The analyst is picked randomly from all online analysts, according to the provided roles (if no roles provided, will fetch all users). + current: The user that executed the command. + enabled: true args: - name: roles @@ -33,7 +44,7 @@ args: - name: username description: When specified, the provided user will be assigned as the incident owner (optional). - name: email - description: When specified, the user of provided email will be assigned as the incident owner (optional) + description: When specified, the user of provided email will be assigned as the incident owner (optional). - name: onCall auto: PREDEFINED predefined: diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index 49bd808bde8f..129c3f1a3cc2 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.14.2", + "currentVersion": "1.14.3", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From aa486119ce56eb898f602929dcfb25c5643540d6 Mon Sep 17 00:00:00 2001 From: Yuval Hayun <70104171+YuvHayun@users.noreply.github.com> Date: Thu, 29 Feb 2024 16:57:11 +0200 Subject: [PATCH 114/272] Cs falcon mobile enhancment (#33072) * added cs-falcon-resolve-mobile-detection command * added RN * failure fixes * added query param & incident type * split fetch idp detections to seperated function and add support for mobile detections. * pre commit fixes * added incident fields * added classifier * added common types rn * update rn * update rn * added incoming mirroring * working mirror in * working mirror out * fixes * temp save * pre commit fixes * pre commit fixes * pre commit fixes * cr fixes --- .../incidentfield-Detection_ID.json | 3 +- .../incidentfield-Display_Name.json | 73 ++-- .../IncidentFields/incidentfield-Email.json | 3 +- .../incidentfield-Last_Update_Time.json | 3 +- .../incidentfield-Vendor_Product.json | 3 +- Packs/CommonTypes/ReleaseNotes/3_4_2.md | 9 + Packs/CommonTypes/pack_metadata.json | 2 +- ...rowdStrike_Falcon_Incident_Classifier.json | 3 +- .../classifier-CrowdStrike_Falcon_Mapper.json | 110 ++++++ ...ssifier-CrowdStrike_Falcon_Mapper_6.5.json | 110 ++++++ ...er-mapper-outgoing-CrowdStrike_Falcon.json | 8 + .../incidentfield-Behaviour_Objective.json | 3 +- .../incidentfield-Behaviour_Scenario.json | 3 +- .../incidentfield-Behaviour_Tactic.json | 3 +- .../incidentfield-Crawled_Timestamp.json | 3 +- .../incidentfield-Detection_Type.json | 3 +- .../incidentfield-Firmware_Build_Time.json | 31 ++ ...identfield-Firmware_build_Fingerprint.json | 31 ++ .../incidentfield-Mobile_Manufacturer.json | 31 ++ ...incidentfield-Mobile_Platform_Version.json | 31 ++ .../incidentfield-Mobile_Product.json | 31 ++ .../incidentfield-Security_Patch_level.json | 31 ++ ...type-CrowdStrikeFalconMobileDetection.json | 28 ++ .../CrowdStrikeFalcon/CrowdStrikeFalcon.py | 350 +++++++++++------- .../CrowdStrikeFalcon/CrowdStrikeFalcon.yml | 77 +++- .../CrowdStrikeFalcon_test.py | 29 +- .../Integrations/CrowdStrikeFalcon/README.md | 59 ++- .../CrowdStrikeFalcon/ReleaseNotes/1_13_1.md | 47 +++ Packs/CrowdStrikeFalcon/pack_metadata.json | 2 +- 29 files changed, 911 insertions(+), 209 deletions(-) create mode 100644 Packs/CommonTypes/ReleaseNotes/3_4_2.md create mode 100644 Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Firmware_Build_Time.json create mode 100644 Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Firmware_build_Fingerprint.json create mode 100644 Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Manufacturer.json create mode 100644 Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Platform_Version.json create mode 100644 Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Product.json create mode 100644 Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Security_Patch_level.json create mode 100644 Packs/CrowdStrikeFalcon/IncidentTypes/incidenttype-CrowdStrikeFalconMobileDetection.json create mode 100644 Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_1.md diff --git a/Packs/CommonTypes/IncidentFields/incidentfield-Detection_ID.json b/Packs/CommonTypes/IncidentFields/incidentfield-Detection_ID.json index de906b84cab5..ffddf447c29b 100644 --- a/Packs/CommonTypes/IncidentFields/incidentfield-Detection_ID.json +++ b/Packs/CommonTypes/IncidentFields/incidentfield-Detection_ID.json @@ -24,7 +24,8 @@ "hidden": false, "associatedTypes": [ "ExtraHop Detection", - "Vectra Detection" + "Vectra Detection", + "CrowdStrike Falcon Mobile Detection" ], "systemAssociatedTypes": null, "associatedToAll": false, diff --git a/Packs/CommonTypes/IncidentFields/incidentfield-Display_Name.json b/Packs/CommonTypes/IncidentFields/incidentfield-Display_Name.json index 99ecb4ca7d8f..76164a439998 100644 --- a/Packs/CommonTypes/IncidentFields/incidentfield-Display_Name.json +++ b/Packs/CommonTypes/IncidentFields/incidentfield-Display_Name.json @@ -1,37 +1,38 @@ -{ - "associatedToAll": false, - "associatedTypes": [ - "IAM - New Hire", - "IAM - Terminate User", - "IAM - Update User", - "User Profile", - "IAM - Sync User", - "IAM - Rehire User", - "Vectra Account", - "CrowdStrike Falcon IDP Detection" - ], - "caseInsensitive": true, - "cliName": "displayname", - "closeForm": false, - "content": true, - "description": "Display Name", - "editForm": true, - "group": 0, - "hidden": false, - "id": "incident_displayname", - "isReadOnly": false, - "locked": false, - "name": "Display Name", - "neverSetAsRequired": false, - "ownerOnly": false, - "required": false, - "sla": 0, - "system": false, - "threshold": 72, - "type": "shortText", - "unmapped": false, - "unsearchable": false, - "useAsKpi": false, - "version": -1, - "fromVersion": "5.0.0" +{ + "associatedToAll": false, + "associatedTypes": [ + "IAM - New Hire", + "IAM - Terminate User", + "IAM - Update User", + "User Profile", + "IAM - Sync User", + "IAM - Rehire User", + "Vectra Account", + "CrowdStrike Falcon IDP Detection", + "CrowdStrike Falcon Mobile Detection" + ], + "caseInsensitive": true, + "cliName": "displayname", + "closeForm": false, + "content": true, + "description": "Display Name", + "editForm": true, + "group": 0, + "hidden": false, + "id": "incident_displayname", + "isReadOnly": false, + "locked": false, + "name": "Display Name", + "neverSetAsRequired": false, + "ownerOnly": false, + "required": false, + "sla": 0, + "system": false, + "threshold": 72, + "type": "shortText", + "unmapped": false, + "unsearchable": false, + "useAsKpi": false, + "version": -1, + "fromVersion": "5.0.0" } \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentFields/incidentfield-Email.json b/Packs/CommonTypes/IncidentFields/incidentfield-Email.json index c973540f9101..0a1ad43799e5 100644 --- a/Packs/CommonTypes/IncidentFields/incidentfield-Email.json +++ b/Packs/CommonTypes/IncidentFields/incidentfield-Email.json @@ -13,7 +13,8 @@ "IAM - Rehire User", "IAM - AD User Activation", "IAM - AD User Deactivation", - "Vectra Account" + "Vectra Account", + "CrowdStrike Falcon Mobile Detection" ], "caseInsensitive": true, "cliName": "email", diff --git a/Packs/CommonTypes/IncidentFields/incidentfield-Last_Update_Time.json b/Packs/CommonTypes/IncidentFields/incidentfield-Last_Update_Time.json index 75dd2b40ed44..9145ee16eb1c 100644 --- a/Packs/CommonTypes/IncidentFields/incidentfield-Last_Update_Time.json +++ b/Packs/CommonTypes/IncidentFields/incidentfield-Last_Update_Time.json @@ -38,7 +38,8 @@ "FreshworksFreshservice Change Request", "Graph Security Alert", "CrowdStrike Falcon IDP Detection", - "Cyberint Incident" + "Cyberint Incident", + "CrowdStrike Falcon Mobile Detection" ], "breachScript": "", "caseInsensitive": true, diff --git a/Packs/CommonTypes/IncidentFields/incidentfield-Vendor_Product.json b/Packs/CommonTypes/IncidentFields/incidentfield-Vendor_Product.json index 9a13bf0dce61..055bbb71d557 100644 --- a/Packs/CommonTypes/IncidentFields/incidentfield-Vendor_Product.json +++ b/Packs/CommonTypes/IncidentFields/incidentfield-Vendor_Product.json @@ -29,7 +29,8 @@ "FireEye NX Alert", "FireEye NX IPS Event", "Microsoft Sentinel Incident", - "CrowdStrike Falcon IDP Detection" + "CrowdStrike Falcon IDP Detection", + "CrowdStrike Falcon Mobile Detection" ], "associatedToAll": false, "unmapped": false, diff --git a/Packs/CommonTypes/ReleaseNotes/3_4_2.md b/Packs/CommonTypes/ReleaseNotes/3_4_2.md new file mode 100644 index 000000000000..ac394d02d13c --- /dev/null +++ b/Packs/CommonTypes/ReleaseNotes/3_4_2.md @@ -0,0 +1,9 @@ +#### Incident Fields + +Added the **CrowdStrike Falcon Mobile Detection** incident type to the following incident fields: + +- **Email** +- **Detection ID** +- **Last Update Time** +- **Vendor Product** +- **Display Name** diff --git a/Packs/CommonTypes/pack_metadata.json b/Packs/CommonTypes/pack_metadata.json index 8e6be00b3c37..f695a9bb5474 100644 --- a/Packs/CommonTypes/pack_metadata.json +++ b/Packs/CommonTypes/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Types", "description": "This Content Pack will get you up and running in no-time and provide you with the most commonly used incident & indicator fields and types.", "support": "xsoar", - "currentVersion": "3.4.1", + "currentVersion": "3.4.2", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Incident_Classifier.json b/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Incident_Classifier.json index 1f17e333b2be..d88345829701 100644 --- a/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Incident_Classifier.json +++ b/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Incident_Classifier.json @@ -10,7 +10,8 @@ "incident": "CrowdStrike Falcon Incident", "IDP detection": "CrowdStrike Falcon IDP Detection", "iom_configurations": "CrowdStrike Falcon IOM Event", - "ioa_events": "CrowdStrike Falcon IOA Event" + "ioa_events": "CrowdStrike Falcon IOA Event", + "MOBILE detection": "CrowdStrike Falcon Mobile Detection" }, "transformer": { "complex": null, diff --git a/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Mapper.json b/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Mapper.json index 733e100895d1..ae393424db2a 100644 --- a/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Mapper.json +++ b/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Mapper.json @@ -547,6 +547,116 @@ } } }, + "CrowdStrike Falcon Mobile Detection": { + "dontMapEventToLabels": true, + "internalMapping": { + "Agent ID": { + "simple": "agent_id" + }, + "State": { + "simple": "status" + }, + "CrowdStrike Falcon Crawled Timestamp": { + "simple": "crawled_timestamp" + }, + "CrowdStrike Falcon Detection Type": { + "simple": "type" + }, + "CrowdStrike Falcon Firmware Build Fingerprint": { + "simple": "firmware_build_fingerprint" + }, + "CrowdStrike Falcon Firmware Build Time": { + "simple": "firmware_build_time" + }, + "Behaviour Objective": { + "simple": "objective" + }, + "Behaviour Scenario": { + "simple": "scenario" + }, + "Behaviour Tactic": { + "simple": "tactic" + }, + "CrowdStrike Falcon Mobile Manufacturer": { + "simple": "mobile_manufacturer" + }, + "CrowdStrike Falcon Mobile Product": { + "simple": "mobile_product" + }, + "CrowdStrike Falcon Mobile platform version": { + "simple": "platform_version" + }, + "CrowdStrike Falcon Security patch level": { + "simple": "security_patch_level" + }, + "Description": { + "simple": "description" + }, + "Device Name": { + "simple": "computer_name" + }, + "External Confidence": { + "simple": "confidence" + }, + "Mobile Device Model": { + "simple": "mobile_model" + }, + "OS": { + "simple": "platform" + }, + "OS Version": { + "simple": "os_version" + }, + "Tactic ID": { + "simple": "tactic_id" + }, + "Technique": { + "simple": "technique" + }, + "Technique ID": { + "simple": "tactic_id" + }, + "Threat Name": { + "simple": "name" + }, + "occurred": { + "simple": "created_timestamp" + }, + "severity": { + "simple": "severity" + }, + "Display Name": { + "simple": "display_name" + }, + "Email": { + "simple": "enrollment_email" + }, + "Detection ID": { + "simple": "mobile_detection_id" + }, + "Vendor Product": { + "simple": "product" + }, + "Last Update Time": { + "simple": "updated_timestamp" + }, + "dbotMirrorDirection": { + "simple": "mirror_direction" + }, + "dbotMirrorId": { + "simple": "composite_id" + }, + "dbotMirrorInstance": { + "simple": "mirror_instance" + }, + "IncomingMirrorError": { + "simple": "in_mirror_error" + }, + "name": { + "simple": "composite_id" + } + } + }, "dbot_classification_incident_type_all": { "dontMapEventToLabels": false, "internalMapping": { diff --git a/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Mapper_6.5.json b/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Mapper_6.5.json index 0e97b8e11b48..76652aad3fc1 100644 --- a/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Mapper_6.5.json +++ b/Packs/CrowdStrikeFalcon/Classifiers/classifier-CrowdStrike_Falcon_Mapper_6.5.json @@ -3,6 +3,116 @@ "feed": false, "id": "CrowdStrike Falcon-Mapper", "mapping": { + "CrowdStrike Falcon Mobile Detection": { + "dontMapEventToLabels": true, + "internalMapping": { + "Agent ID": { + "simple": "agent_id" + }, + "State": { + "simple": "status" + }, + "CrowdStrike Falcon Crawled Timestamp": { + "simple": "crawled_timestamp" + }, + "CrowdStrike Falcon Detection Type": { + "simple": "type" + }, + "CrowdStrike Falcon Firmware Build Fingerprint": { + "simple": "firmware_build_fingerprint" + }, + "CrowdStrike Falcon Firmware Build Time": { + "simple": "firmware_build_time" + }, + "Behaviour Objective": { + "simple": "objective" + }, + "Behaviour Scenario": { + "simple": "scenario" + }, + "Behaviour Tactic": { + "simple": "tactic" + }, + "CrowdStrike Falcon Mobile Manufacturer": { + "simple": "mobile_manufacturer" + }, + "CrowdStrike Falcon Mobile Product": { + "simple": "mobile_product" + }, + "CrowdStrike Falcon Mobile platform version": { + "simple": "platform_version" + }, + "CrowdStrike Falcon Security patch level": { + "simple": "security_patch_level" + }, + "Description": { + "simple": "description" + }, + "Device Name": { + "simple": "computer_name" + }, + "External Confidence": { + "simple": "confidence" + }, + "Mobile Device Model": { + "simple": "mobile_model" + }, + "OS": { + "simple": "platform" + }, + "OS Version": { + "simple": "os_version" + }, + "Tactic ID": { + "simple": "tactic_id" + }, + "Technique": { + "simple": "technique" + }, + "Technique ID": { + "simple": "tactic_id" + }, + "Threat Name": { + "simple": "name" + }, + "occurred": { + "simple": "created_timestamp" + }, + "severity": { + "simple": "severity" + }, + "Display Name": { + "simple": "display_name" + }, + "Email": { + "simple": "enrollment_email" + }, + "Detection ID": { + "simple": "mobile_detection_id" + }, + "Vendor Product": { + "simple": "product" + }, + "Last Update Time": { + "simple": "updated_timestamp" + }, + "dbotMirrorDirection": { + "simple": "mirror_direction" + }, + "dbotMirrorId": { + "simple": "composite_id" + }, + "dbotMirrorInstance": { + "simple": "mirror_instance" + }, + "IncomingMirrorError": { + "simple": "in_mirror_error" + }, + "name": { + "simple": "mobile_detection_id" + } + } + }, "CrowdStrike Falcon IOA Event": { "dontMapEventToLabels": false, "internalMapping": { diff --git a/Packs/CrowdStrikeFalcon/Classifiers/classifier-mapper-outgoing-CrowdStrike_Falcon.json b/Packs/CrowdStrikeFalcon/Classifiers/classifier-mapper-outgoing-CrowdStrike_Falcon.json index a4e879562aff..26f0fd0449fb 100644 --- a/Packs/CrowdStrikeFalcon/Classifiers/classifier-mapper-outgoing-CrowdStrike_Falcon.json +++ b/Packs/CrowdStrikeFalcon/Classifiers/classifier-mapper-outgoing-CrowdStrike_Falcon.json @@ -19,6 +19,14 @@ } } }, + "CrowdStrike Falcon Mobile Detection": { + "dontMapEventToLabels": true, + "internalMapping": { + "status": { + "simple": "state" + } + } + }, "CrowdStrike Falcon Incident": { "dontMapEventToLabels": true, "internalMapping": { diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Objective.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Objective.json index c2f99d44128e..a15dec680e16 100644 --- a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Objective.json +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Objective.json @@ -2,7 +2,8 @@ "associatedToAll": false, "associatedTypes": [ "CrowdStrike Falcon Detection", - "CrowdStrike Falcon IDP Detection" + "CrowdStrike Falcon IDP Detection", + "CrowdStrike Falcon Mobile Detection" ], "breachScript": "", "caseInsensitive": true, diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Scenario.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Scenario.json index 08cf836bf9a5..6aabb2f2f260 100644 --- a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Scenario.json +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Scenario.json @@ -2,7 +2,8 @@ "associatedToAll": false, "associatedTypes": [ "CrowdStrike Falcon Detection", - "CrowdStrike Falcon IDP Detection" + "CrowdStrike Falcon IDP Detection", + "CrowdStrike Falcon Mobile Detection" ], "breachScript": "", "caseInsensitive": true, diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Tactic.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Tactic.json index 60e08e5f0eac..9cd865aff508 100644 --- a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Tactic.json +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Behaviour_Tactic.json @@ -2,7 +2,8 @@ "associatedToAll": false, "associatedTypes": [ "CrowdStrike Falcon Detection", - "CrowdStrike Falcon IDP Detection" + "CrowdStrike Falcon IDP Detection", + "CrowdStrike Falcon Mobile Detection" ], "breachScript": "", "caseInsensitive": true, diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Crawled_Timestamp.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Crawled_Timestamp.json index 56b7b0de848b..63c28204a34c 100644 --- a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Crawled_Timestamp.json +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Crawled_Timestamp.json @@ -19,7 +19,8 @@ "hidden": false, "openEnded": false, "associatedTypes": [ - "CrowdStrike Falcon IDP Detection" + "CrowdStrike Falcon IDP Detection", + "CrowdStrike Falcon Mobile Detection" ], "associatedToAll": false, "unmapped": false, diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Detection_Type.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Detection_Type.json index bd9c4f313b98..c850fec61060 100644 --- a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Detection_Type.json +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Detection_Type.json @@ -19,7 +19,8 @@ "hidden": false, "openEnded": false, "associatedTypes": [ - "CrowdStrike Falcon IDP Detection" + "CrowdStrike Falcon IDP Detection", + "CrowdStrike Falcon Mobile Detection" ], "associatedToAll": false, "unmapped": false, diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Firmware_Build_Time.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Firmware_Build_Time.json new file mode 100644 index 000000000000..01b1ec653ca8 --- /dev/null +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Firmware_Build_Time.json @@ -0,0 +1,31 @@ +{ + "id": "incident_crowdstrikefalconfirmwarebuildtime", + "version": -1, + "modified": "2024-02-25T15:47:43.680520106Z", + "name": "CrowdStrike Falcon Firmware Build Time", + "ownerOnly": false, + "cliName": "crowdstrikefalconfirmwarebuildtime", + "type": "date", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "CrowdStrike Falcon Mobile Detection" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": true, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Firmware_build_Fingerprint.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Firmware_build_Fingerprint.json new file mode 100644 index 000000000000..cc559f616828 --- /dev/null +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Firmware_build_Fingerprint.json @@ -0,0 +1,31 @@ +{ + "id": "incident_crowdstrikefalconfirmwarebuildfingerprint", + "version": -1, + "modified": "2024-02-25T15:46:11.027991681Z", + "name": "CrowdStrike Falcon Firmware Build Fingerprint", + "ownerOnly": false, + "cliName": "crowdstrikefalconfirmwarebuildfingerprint", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "CrowdStrike Falcon Mobile Detection" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": true, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Manufacturer.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Manufacturer.json new file mode 100644 index 000000000000..d3ce05edb3f9 --- /dev/null +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Manufacturer.json @@ -0,0 +1,31 @@ +{ + "id": "incident_crowdstrikefalconmobilemanufacturer", + "version": -1, + "modified": "2024-02-25T15:49:57.121260285Z", + "name": "CrowdStrike Falcon Mobile Manufacturer", + "ownerOnly": false, + "cliName": "crowdstrikefalconmobilemanufacturer", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "CrowdStrike Falcon Mobile Detection" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": true, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Platform_Version.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Platform_Version.json new file mode 100644 index 000000000000..e135c3d423d9 --- /dev/null +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Platform_Version.json @@ -0,0 +1,31 @@ +{ + "id": "incident_crowdstrikefalconmobileplatformversion", + "version": -1, + "modified": "2024-02-25T15:48:24.075185814Z", + "name": "CrowdStrike Falcon Mobile platform version", + "ownerOnly": false, + "cliName": "crowdstrikefalconmobileplatformversion", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "CrowdStrike Falcon Mobile Detection" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": true, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Product.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Product.json new file mode 100644 index 000000000000..6f8b3e38d33b --- /dev/null +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Mobile_Product.json @@ -0,0 +1,31 @@ +{ + "id": "incident_crowdstrikefalconmobileproduct", + "version": -1, + "modified": "2024-02-25T15:49:42.375129493Z", + "name": "CrowdStrike Falcon Mobile Product", + "ownerOnly": false, + "cliName": "crowdstrikefalconmobileproduct", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "CrowdStrike Falcon Mobile Detection" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": true, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Security_Patch_level.json b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Security_Patch_level.json new file mode 100644 index 000000000000..9a6f11951af2 --- /dev/null +++ b/Packs/CrowdStrikeFalcon/IncidentFields/incidentfield-Security_Patch_level.json @@ -0,0 +1,31 @@ +{ + "id": "incident_crowdstrikefalconsecuritypatchlevel", + "version": -1, + "modified": "2024-02-25T15:49:12.710595921Z", + "name": "CrowdStrike Falcon Security patch level", + "ownerOnly": false, + "cliName": "crowdstrikefalconsecuritypatchlevel", + "type": "shortText", + "closeForm": false, + "editForm": true, + "required": false, + "neverSetAsRequired": false, + "isReadOnly": false, + "useAsKpi": false, + "locked": false, + "system": false, + "content": true, + "group": 0, + "hidden": false, + "openEnded": false, + "associatedTypes": [ + "CrowdStrike Falcon Mobile Detection" + ], + "associatedToAll": false, + "unmapped": false, + "unsearchable": true, + "caseInsensitive": true, + "sla": 0, + "threshold": 72, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/IncidentTypes/incidenttype-CrowdStrikeFalconMobileDetection.json b/Packs/CrowdStrikeFalcon/IncidentTypes/incidenttype-CrowdStrikeFalconMobileDetection.json new file mode 100644 index 000000000000..da8ac07c768a --- /dev/null +++ b/Packs/CrowdStrikeFalcon/IncidentTypes/incidenttype-CrowdStrikeFalconMobileDetection.json @@ -0,0 +1,28 @@ +{ + "id": "CrowdStrike Falcon Mobile Detection", + "version": -1, + "vcShouldIgnore": false, + "locked": false, + "name": "CrowdStrike Falcon Mobile Detection", + "prevName": "CrowdStrike Falcon Mobile Detection", + "color": "#E5CF7C", + "hours": 0, + "days": 0, + "weeks": 0, + "hoursR": 0, + "daysR": 0, + "weeksR": 0, + "system": false, + "readonly": false, + "default": false, + "autorun": false, + "disabled": false, + "reputationCalc": 0, + "onChangeRepAlg": 0, + "detached": false, + "extractSettings": { + "mode": "Specific", + "fieldCliNameToExtractSettings": {} + }, + "fromVersion": "6.10.0" +} \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py index 17e12cad5c83..0c9040978ca1 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.py @@ -20,14 +20,18 @@ ''' GLOBALS/PARAMS ''' INTEGRATION_NAME = 'CrowdStrike Falcon' IDP_DETECTION = "IDP detection" -CLIENT_ID = demisto.params().get('credentials', {}).get('identifier') or demisto.params().get('client_id') -SECRET = demisto.params().get('credentials', {}).get('password') or demisto.params().get('secret') +MOBILE_DETECTION = "MOBILE detection" +IDP_DETECTION_FETCH_TYPE = "IDP Detection" +MOBILE_DETECTION_FETCH_TYPE = "Mobile Detection" +PARAMS = demisto.params() +CLIENT_ID = PARAMS.get('credentials', {}).get('identifier') or PARAMS.get('client_id') +SECRET = PARAMS.get('credentials', {}).get('password') or PARAMS.get('secret') # Remove trailing slash to prevent wrong URL path to service -SERVER = demisto.params()['url'].removesuffix('/') +SERVER = PARAMS['url'].removesuffix('/') # Should we use SSL -USE_SSL = not demisto.params().get('insecure', False) +USE_SSL = not PARAMS.get('insecure', False) # How many time before the first fetch to retrieve incidents -FETCH_TIME = demisto.params().get('fetch_time', '3 days') +FETCH_TIME = PARAMS.get('fetch_time', '3 days') BYTE_CREDS = f'{CLIENT_ID}:{SECRET}'.encode() # Headers to be sent in requests HEADERS = { @@ -37,9 +41,9 @@ } # Note: True life time of token is actually 30 mins TOKEN_LIFE_TIME = 28 -INCIDENTS_PER_FETCH = int(demisto.params().get('incidents_per_fetch', 15)) +INCIDENTS_PER_FETCH = int(PARAMS.get('incidents_per_fetch', 15)) DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ' -DETECTION_DATE_FORMAT = IDP_DATE_FORMAT = IOM_DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' +DETECTION_DATE_FORMAT = IOM_DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ' DEFAULT_TIMEOUT = 30 # Remove proxy if not set to true in params handle_proxy() @@ -228,7 +232,7 @@ ''' MIRRORING DICTIONARIES & PARAMS ''' DETECTION_STATUS = {'new', 'in_progress', 'true_positive', 'false_positive', 'ignored', 'closed', 'reopened'} -IDP_DETECTION_STATUS = {'new', 'in_progress', 'closed', 'reopened'} +IDP_AND_MOBILE_DETECTION_STATUS = {'new', 'in_progress', 'closed', 'reopened'} CS_FALCON_DETECTION_OUTGOING_ARGS = {'status': f'Updated detection status, one of {"/".join(DETECTION_STATUS)}'} @@ -279,7 +283,7 @@ class IncidentType(Enum): INCIDENT = 'inc' DETECTION = 'ldt' - IDP_DETECTION = ':ind:' + IDP_OR_MOBILE_DETECTION = ':ind:' IOM_CONFIGURATIONS = 'iom_configurations' IOA_EVENTS = 'ioa_events' @@ -567,26 +571,28 @@ def incident_to_incident_context(incident): return incident_context -def idp_detection_to_incident_context(idp_detection): +def detection_to_incident_context(detection, detection_type, start_time_key: str = 'start_time'): """ - Creates an incident context of an IDP detection. + Creates an incident context of an IDP/Mobile detection. - :type idp_detection: ``dict`` - :param idp_detection: Single IDP detection object + :type detection: ``dict`` + :param detection: Single detection object. - :return: Incident context representation of an IDP detection. - :rtype ``dict`` - """ - add_mirroring_fields(idp_detection) - if status := idp_detection.get('status'): - idp_detection['status'] = status + :return: Incident context representation of an IDP/Mobile detection. + :rtype ``dict`` + """ + add_mirroring_fields(detection) incident_context = { - 'name': f'IDP Detection ID: {idp_detection.get("composite_id")}', - 'occurred': idp_detection.get('start_time'), - 'last_updated': idp_detection.get('updated_timestamp'), - 'rawJSON': json.dumps(idp_detection) + 'occurred': detection.get(start_time_key), + 'rawJSON': json.dumps(detection) } + if detection_type == IDP_DETECTION_FETCH_TYPE: + incident_context['name'] = f'{detection_type} ID: {detection.get("composite_id")}' + incident_context['last_updated'] = detection.get('updated_timestamp') + elif detection_type == MOBILE_DETECTION_FETCH_TYPE: + incident_context['name'] = f'{detection_type} ID: {detection.get("mobile_detection_id")}' + incident_context['severity'] = detection.get('severity') return incident_context @@ -1397,7 +1403,7 @@ def get_incidents_ids(last_created_timestamp=None, filter_arg=None, offset: int return response -def get_idp_detections_ids(filter_arg=None, offset: int = 0, limit=INCIDENTS_PER_FETCH): +def get_detections_ids(filter_arg=None, offset: int = 0, limit=INCIDENTS_PER_FETCH, product_type='idp'): """ Send a request to retrieve IDP detections IDs. @@ -1420,7 +1426,7 @@ def get_idp_detections_ids(filter_arg=None, offset: int = 0, limit=INCIDENTS_PER params['limit'] = limit endpoint_url = "/alerts/queries/alerts/v1" response = http_request('GET', endpoint_url, params) - demisto.debug(f"CrowdStrikeFalconMsg: Getting idp detections from {endpoint_url} with {params=}. {response=}") + demisto.debug(f"CrowdStrikeFalconMsg: Getting {product_type} detections from {endpoint_url} with {params=}. {response=}") return response @@ -1435,9 +1441,9 @@ def get_incidents_entities(incidents_ids: list): return response -def get_idp_detection_entities(incidents_ids: list): +def get_detection_entities(incidents_ids: list): """ - Send a request to retrieve IDP detection entities. + Send a request to retrieve IDP and mobile detection entities. :type incidents_ids: ``list`` :param incidents_ids: The list of ids to search their entities. @@ -1844,9 +1850,9 @@ def resolve_detection(ids, status, assigned_to_uuid, show_in_ui, comment): return http_request('PATCH', '/detects/entities/detects/v2', data=data) -def resolve_idp_detection(ids, status): +def resolve_idp_or_mobile_detection(ids, status): """ - Send a request to update IDP detection status. + Send a request to update IDP/Mobile detection status. :type ids: ``list`` :param ids: The list of ids to update. :type status: ``str`` @@ -1994,9 +2000,9 @@ def update_detection_request(ids: list[str], status: str) -> dict: return resolve_detection(ids=ids, status=status, assigned_to_uuid=None, show_in_ui=None, comment=None) -def update_idp_detection_request(ids: list[str], status: str) -> dict: +def update_idp_or_mobile_detection_request(ids: list[str], status: str) -> dict: """ - Manage the status to send to update to for IDP detections. + Manage the status to send to update to for IDP/Mobile detections. :type ids: ``list`` :param ids: The list of ids to update. :type status: ``str`` @@ -2004,10 +2010,10 @@ def update_idp_detection_request(ids: list[str], status: str) -> dict: :return: The response. :rtype ``dict`` """ - if status not in IDP_DETECTION_STATUS: + if status not in IDP_AND_MOBILE_DETECTION_STATUS: raise DemistoException(f'CrowdStrike Falcon Error: ' - f'Status given is {status} and it is not in {IDP_DETECTION_STATUS}') - return resolve_idp_detection(ids=ids, status=status) + f'Status given is {status} and it is not in {IDP_AND_MOBILE_DETECTION_STATUS}') + return resolve_idp_or_mobile_detection(ids=ids, status=status) def list_host_groups(filter: str | None, limit: str | None, offset: str | None) -> dict: @@ -2196,11 +2202,12 @@ def get_remote_data_command(args: dict[str, Any]): demisto.debug(f'Update detection {remote_incident_id} with fields: {updated_object}') set_xsoar_detection_entries(updated_object, entries, remote_incident_id) # sets in place - elif incident_type == IncidentType.IDP_DETECTION: - mirrored_data, updated_object = get_remote_idp_detection_data(remote_incident_id) + elif incident_type == IncidentType.IDP_OR_MOBILE_DETECTION: + mirrored_data, updated_object, detection_type = get_remote_idp_or_mobile_detection_data(remote_incident_id) if updated_object: - demisto.debug(f'Update IDP detection {remote_incident_id} with fields: {updated_object}') - set_xsoar_idp_detection_entries(updated_object, entries, remote_incident_id) # sets in place + demisto.debug(f'Update {detection_type} detection {remote_incident_id} with fields: {updated_object}') + set_xsoar_idp_or_mobile_detection_entries( + updated_object, entries, remote_incident_id, detection_type) # sets in place else: # this is here as prints can disrupt mirroring @@ -2226,8 +2233,8 @@ def find_incident_type(remote_incident_id: str): return IncidentType.INCIDENT if remote_incident_id[0:3] == IncidentType.DETECTION.value: return IncidentType.DETECTION - if IncidentType.IDP_DETECTION.value in remote_incident_id: - return IncidentType.IDP_DETECTION + if IncidentType.IDP_OR_MOBILE_DETECTION.value in remote_incident_id: + return IncidentType.IDP_OR_MOBILE_DETECTION return None @@ -2264,27 +2271,32 @@ def get_remote_detection_data(remote_incident_id: str): return mirrored_data, updated_object -def get_remote_idp_detection_data(remote_incident_id): +def get_remote_idp_or_mobile_detection_data(remote_incident_id): """ - Gets the relevant IDP detection entity from the remote system (CrowdStrike Falcon). + Gets the relevant IDP or Mobile detection entity from the remote system (CrowdStrike Falcon). :type remote_incident_id: ``str`` :param remote_incident_id: The incident id to return its information. - :return: The IDP detection entity. + :return: The IDP or Mobile detection entity. :rtype ``dict`` :return: The object with the updated fields. :rtype ``dict`` + :return: The detection type (idp or mobile). + :rtype ``str`` """ - mirrored_data_list = get_idp_detection_entities([remote_incident_id]).get('resources', []) # a list with one dict in it + mirrored_data_list = get_detection_entities([remote_incident_id]).get('resources', []) # a list with one dict in it mirrored_data = mirrored_data_list[0] - - if 'status' in mirrored_data: - mirrored_data['status'] = mirrored_data.get('status') - - updated_object: dict[str, Any] = {'incident_type': IDP_DETECTION} + detection_type = '' + updated_object: dict[str, Any] = {} + if 'idp' in mirrored_data['product']: + updated_object = {'incident_type': IDP_DETECTION} + detection_type = 'IDP' + if 'mobile' in mirrored_data['product']: + updated_object = {'incident_type': MOBILE_DETECTION} + detection_type = 'Mobile' set_updated_object(updated_object, mirrored_data, ['status']) - return mirrored_data, updated_object + return mirrored_data, updated_object, detection_type def set_xsoar_incident_entries(updated_object: dict[str, Any], entries: list, remote_incident_id: str): @@ -2303,7 +2315,8 @@ def set_xsoar_detection_entries(updated_object: dict[str, Any], entries: list, r reopen_in_xsoar(entries, remote_detection_id, 'Detection') -def set_xsoar_idp_detection_entries(updated_object: dict[str, Any], entries: list, remote_idp_detection_id: str): +def set_xsoar_idp_or_mobile_detection_entries(updated_object: dict[str, Any], entries: list, + remote_idp_detection_id: str, incident_type_name: str): """ Send the updated object to the relevant status handler @@ -2319,9 +2332,9 @@ def set_xsoar_idp_detection_entries(updated_object: dict[str, Any], entries: lis """ if demisto.params().get('close_incident'): if updated_object.get('status') == 'closed': - close_in_xsoar(entries, remote_idp_detection_id, IDP_DETECTION) - elif updated_object.get('status') in (set(IDP_DETECTION_STATUS) - {'closed'}): - reopen_in_xsoar(entries, remote_idp_detection_id, IDP_DETECTION) + close_in_xsoar(entries, remote_idp_detection_id, incident_type_name) + elif updated_object.get('status') in (set(IDP_AND_MOBILE_DETECTION_STATUS) - {'closed'}): + reopen_in_xsoar(entries, remote_idp_detection_id, incident_type_name) def close_in_xsoar(entries: list, remote_incident_id: str, incident_type_name: str): @@ -2405,9 +2418,14 @@ def get_modified_remote_data_command(args: dict[str, Any]): if 'Detections' in fetch_types or "Endpoint Detection" in fetch_types: raw_ids += get_fetch_detections(last_updated_timestamp=last_update_timestamp, has_limit=False).get('resources', []) - if "IDP Detection" in fetch_types: - raw_ids += get_idp_detections_ids( - filter_arg=f"updated_timestamp:>'{last_update_utc.strftime(IDP_DATE_FORMAT)}'+product:'idp'" + if IDP_DETECTION_FETCH_TYPE in fetch_types: + raw_ids += get_detections_ids( + filter_arg=f"updated_timestamp:>'{last_update_utc.strftime(DETECTION_DATE_FORMAT)}'+product:'idp'" + ).get('resources', []) + + if MOBILE_DETECTION_FETCH_TYPE in fetch_types: + raw_ids += get_detections_ids( + filter_arg=f"updated_timestamp:>'{last_update_utc.strftime(DETECTION_DATE_FORMAT)}'+product:'mobile'" ).get('resources', []) modified_ids_to_mirror = list(map(str, raw_ids)) @@ -2445,10 +2463,10 @@ def update_remote_system_command(args: dict[str, Any]) -> str: if result: demisto.debug(f'Detection updated successfully. Result: {result}') - elif incident_type == IncidentType.IDP_DETECTION: - result = update_remote_idp_detection(delta, parsed_args.inc_status, remote_incident_id) + elif incident_type == IncidentType.IDP_OR_MOBILE_DETECTION: + result = update_remote_idp_or_mobile_detection(delta, parsed_args.inc_status, remote_incident_id) if result: - demisto.debug(f'IDP Detection updated successfully. Result: {result}') + demisto.debug(f'IDP/Mobile Detection updated successfully. Result: {result}') else: raise Exception(f'Executed update-remote-system command with undefined id: {remote_incident_id}') @@ -2489,25 +2507,25 @@ def update_remote_detection(delta, inc_status: IncidentStatus, detection_id: str return '' -def update_remote_idp_detection(delta, inc_status: IncidentStatus, detection_id: str) -> str: +def update_remote_idp_or_mobile_detection(delta, inc_status: IncidentStatus, detection_id: str) -> str: """ - Sends the request the request to update the relevant IDP detection entity. + Sends the request the request to update the relevant IDP/Mobile detection entity. :type delta: ``dict`` :param delta: The modified fields. :type inc_status: ``IncidentStatus`` - :param inc_status: The IDP detection status. + :param inc_status: The IDP/Mobile detection status. :type detection_id: ``str`` - :param detection_id: The IDP detection ID to update. + :param detection_id: The IDP/Mobile detection ID to update. """ if inc_status == IncidentStatus.DONE and close_in_cs_falcon(delta): - demisto.debug(f'Closing IDP detection with remote ID {detection_id} in remote system.') - return str(update_idp_detection_request([detection_id], 'closed')) + demisto.debug(f'Closing IDP/Mobile detection with remote ID {detection_id} in remote system.') + return str(update_idp_or_mobile_detection_request([detection_id], 'closed')) # status field in CS Falcon is mapped to State field in XSOAR elif 'status' in delta: demisto.debug(f'Detection with remote ID {detection_id} status will change to "{delta.get("status")}" in remote system.') - return str(update_idp_detection_request([detection_id], delta.get('status'))) + return str(update_idp_or_mobile_detection_request([detection_id], delta.get('status'))) return '' @@ -2617,18 +2635,21 @@ def fetch_incidents(): idp_detections: list = [] iom_incidents: list[dict[str, Any]] = [] ioa_incidents: list[dict[str, Any]] = [] + mobile_detections: list[dict[str, Any]] = [] last_run = demisto.getLastRun() demisto.debug(f'CrowdStrikeFalconMsg: Current last run object is {last_run}') if not last_run: - last_run = [{}, {}, {}, {}, {}] + last_run = [{}, {}, {}, {}, {}, {}] last_run = migrate_last_run(last_run) current_fetch_info_detections: dict = last_run[0] current_fetch_info_incidents: dict = last_run[1] current_fetch_info_idp_detections: dict = {} if len(last_run) < 3 else last_run[2] iom_last_run: dict = {} if len(last_run) < 4 else last_run[3] ioa_last_run: dict = {} if len(last_run) < 5 else last_run[4] - fetch_incidents_or_detections = demisto.params().get('fetch_incidents_or_detections', "") - look_back = int(demisto.params().get('look_back') or 1) + current_fetch_info_mobile_detections: dict = {} if len(last_run) < 6 else last_run[5] + params = demisto.params() + fetch_incidents_or_detections = params.get('fetch_incidents_or_detections', "") + look_back = int(params.get('look_back') or 1) fetch_limit = INCIDENTS_PER_FETCH demisto.debug(f"CrowdstrikeFalconMsg: Starting fetch incidents with {fetch_incidents_or_detections}") @@ -2641,7 +2662,7 @@ def fetch_incidents(): date_format=DETECTION_DATE_FORMAT) fetch_limit = current_fetch_info_detections.get('limit') or INCIDENTS_PER_FETCH incident_type = 'detection' - fetch_query = demisto.params().get('fetch_query') + fetch_query = params.get('fetch_query') if fetch_query: fetch_query = f"created_timestamp:>'{start_fetch_time}'+{fetch_query}" response = get_fetch_detections(filter_arg=fetch_query, limit=fetch_limit, offset=detections_offset) @@ -2698,7 +2719,7 @@ def fetch_incidents(): incident_type = 'incident' - fetch_query = demisto.params().get('incidents_fetch_query') + fetch_query = params.get('incidents_fetch_query') if fetch_query: fetch_query = f"start:>'{start_fetch_time}'+{fetch_query}" @@ -2738,55 +2759,32 @@ def fetch_incidents(): new_offset=incidents_offset) demisto.debug(f"CrowdstrikeFalconMsg: Ending fetch Incidents. Fetched {len(incidents)}") - if "IDP Detection" in fetch_incidents_or_detections: - idp_detections_offset: int = current_fetch_info_idp_detections.get('offset') or 0 - - start_fetch_time, end_fetch_time = get_fetch_run_time_range(last_run=current_fetch_info_idp_detections, - first_fetch=FETCH_TIME, - look_back=look_back, - date_format=IDP_DATE_FORMAT) - fetch_limit = current_fetch_info_idp_detections.get('limit') or INCIDENTS_PER_FETCH - fetch_query = demisto.params().get('idp_detections_fetch_query', "") - filter = f"product:'idp'+created_timestamp:>'{start_fetch_time}'" - - if fetch_query: - filter += f"+{fetch_query}" - response = get_idp_detections_ids(filter_arg=filter, limit=fetch_limit, offset=idp_detections_offset) - idp_detections_ids: list[dict] = demisto.get(response, "resources", []) - total_idp_detections = demisto.get(response, "meta.pagination.total") - idp_detections_offset = calculate_new_offset(idp_detections_offset, len(idp_detections_ids), total_idp_detections) - if idp_detections_offset: - demisto.debug(f"CrowdStrikeFalconMsg: The new idp detections offset is {idp_detections_offset}") - - if idp_detections_ids: - raw_res = get_idp_detection_entities(idp_detections_ids) - if "resources" in raw_res: - full_detections = demisto.get(raw_res, "resources") - for idp_detection in full_detections: - idp_detection['incident_type'] = IDP_DETECTION - idp_detection_to_context = idp_detection_to_incident_context(idp_detection) - idp_detections.append(idp_detection_to_context) - - idp_detections = filter_incidents_by_duplicates_and_limit(incidents_res=idp_detections, - last_run=current_fetch_info_idp_detections, - fetch_limit=INCIDENTS_PER_FETCH, id_field='name') - - current_fetch_info_idp_detections = update_last_run_object(last_run=current_fetch_info_idp_detections, - incidents=idp_detections, - fetch_limit=fetch_limit, - start_fetch_time=start_fetch_time, - end_fetch_time=end_fetch_time, - look_back=look_back, - created_time_field='occurred', - id_field='name', - date_format=IDP_DATE_FORMAT, - new_offset=idp_detections_offset) - demisto.debug(f"CrowdstrikeFalconMsg: Ending fetch idp_detections. Fetched {len(idp_detections)}") + if IDP_DETECTION_FETCH_TYPE in fetch_incidents_or_detections: + idp_detections, current_fetch_info_idp_detections = fetch_idp_and_mobile_detections( + current_fetch_info_idp_detections, + look_back=look_back, + fetch_query=params.get( + 'idp_detections_fetch_query', ""), + detections_type=IDP_DETECTION, + product_type='idp', + detection_name_prefix=IDP_DETECTION_FETCH_TYPE, + start_time_key='start_time') + + if MOBILE_DETECTION_FETCH_TYPE in fetch_incidents_or_detections: + mobile_detections, current_fetch_info_mobile_detections = fetch_idp_and_mobile_detections( + current_fetch_info_mobile_detections, + look_back=look_back, + fetch_query=params.get( + 'mobile_detections_fetch_query', ""), + detections_type=MOBILE_DETECTION, + product_type='mobile', + detection_name_prefix=MOBILE_DETECTION_FETCH_TYPE, + start_time_key='timestamp') if 'Indicator of Misconfiguration' in fetch_incidents_or_detections: demisto.debug('Fetching Indicator of Misconfiguration incidents') demisto.debug(f'{iom_last_run=}') - fetch_query = demisto.params().get('iom_fetch_query', '') + fetch_query = params.get('iom_fetch_query', '') validate_iom_fetch_query(iom_fetch_query=fetch_query) last_resource_ids, iom_next_token, last_scan_time, first_fetch_timestamp = get_current_fetch_data( @@ -2820,7 +2818,7 @@ def fetch_incidents(): if 'Indicator of Attack' in fetch_incidents_or_detections: demisto.debug('Fetching Indicator of Attack incidents') demisto.debug(f'{ioa_last_run=}') - fetch_query = demisto.params().get('ioa_fetch_query', '') + fetch_query = params.get('ioa_fetch_query', '') validate_ioa_fetch_query(ioa_fetch_query=fetch_query) last_fetch_event_ids, ioa_next_token, last_date_time_since, _ = get_current_fetch_data( @@ -2850,8 +2848,71 @@ def fetch_incidents(): ioa_last_run = {'ioa_next_token': ioa_new_next_token, 'last_date_time_since': new_date_time_since, 'last_fetch_query': ioa_fetch_query, 'last_event_ids': ioa_event_ids or last_fetch_event_ids} demisto.setLastRun([current_fetch_info_detections, current_fetch_info_incidents, current_fetch_info_idp_detections, - iom_last_run, ioa_last_run]) - return incidents + detections + idp_detections + iom_incidents + ioa_incidents + iom_last_run, ioa_last_run, current_fetch_info_mobile_detections]) + return incidents + detections + idp_detections + iom_incidents + ioa_incidents + mobile_detections + + +def fetch_idp_and_mobile_detections(current_fetch_info: dict, look_back: int, product_type: str, + fetch_query: str, detections_type: str, detection_name_prefix: str, + start_time_key: str) -> tuple[List, dict]: + """The fetch logic for idp and mobile detections. + + Args: + current_fetch_info (dict): The last run object. + look_back (int): The number of minutes to lookback. + product_type (str): The product_type, used for debug & query. + fetch_query (str): The user's query param. + detections_type (str): The detection type, used for debugging and context save. + detection_name_prefix (str): The name prefix for the fetched incidents. + start_time_key (str): The key to save as the incident occurred time. + + Returns: + tuple[List, dict]: The list of the fetched incidents and the updated last object. + """ + detections: List = [] + offset: int = current_fetch_info.get('offset') or 0 + + start_fetch_time, end_fetch_time = get_fetch_run_time_range(last_run=current_fetch_info, + first_fetch=FETCH_TIME, + look_back=look_back, + date_format=DETECTION_DATE_FORMAT) + fetch_limit = current_fetch_info.get('limit') or INCIDENTS_PER_FETCH + filter = f"product:'{product_type}'+created_timestamp:>'{start_fetch_time}'" + + if fetch_query: + filter += f"+{fetch_query}" + response = get_detections_ids(filter_arg=filter, limit=fetch_limit, offset=offset, product_type=product_type) + detections_ids: list[dict] = demisto.get(response, "resources", []) + total_detections = demisto.get(response, "meta.pagination.total") + offset = calculate_new_offset(offset, len(detections_ids), total_detections) + if offset: + demisto.debug(f"CrowdStrikeFalconMsg: The new {detections_type} offset is {offset}") + + if detections_ids: + raw_res = get_detection_entities(detections_ids) + if "resources" in raw_res: + full_detections = demisto.get(raw_res, "resources") + for detection in full_detections: + detection['incident_type'] = detections_type + detection_to_context = detection_to_incident_context(detection, detection_name_prefix, start_time_key) + detections.append(detection_to_context) + + detections = filter_incidents_by_duplicates_and_limit(incidents_res=detections, + last_run=current_fetch_info, + fetch_limit=INCIDENTS_PER_FETCH, id_field='name') + + current_fetch_info = update_last_run_object(last_run=current_fetch_info, + incidents=detections, + fetch_limit=fetch_limit, + start_fetch_time=start_fetch_time, + end_fetch_time=end_fetch_time, + look_back=look_back, + created_time_field='occurred', + id_field='name', + date_format=DETECTION_DATE_FORMAT, + new_offset=offset) + demisto.debug(f"CrowdstrikeFalconMsg: Ending fetch {detections_type}. Fetched {len(detections)}") + return detections, current_fetch_info def parse_ioa_iom_incidents(fetched_data: list[dict[str, Any]], last_date: str, @@ -6402,9 +6463,9 @@ def cs_falcon_cspm_update_policy_settings_command(args: dict[str, Any]) -> Comma return CommandResults(readable_output=f'Policy {policy_id} was updated successfully') -def resolve_identity_detection_prepare_body_request(ids: list[str], - action_params_values: dict[str, Any]) -> dict[str, Any]: - """Create the body of the request to resolve an identity detection. +def resolve_detections_prepare_body_request(ids: list[str], + action_params_values: dict[str, Any]) -> dict[str, Any]: + """Create the body of the request to resolve detections. Args: ids (list[str]): The IDs of the detections. @@ -6427,8 +6488,8 @@ def resolve_identity_detection_prepare_body_request(ids: list[str], return {'action_parameters': action_params, 'ids': ids} -def resolve_identity_detection_request(ids: list[str], **kwargs) -> dict[str, Any]: - """Do an API call to resolve an identity detection. +def resolve_detections_request(ids: list[str], **kwargs) -> dict[str, Any]: + """Do an API call to resolve detections. Args: ids (list[str]): The IDs of the detections. @@ -6436,12 +6497,36 @@ def resolve_identity_detection_request(ids: list[str], **kwargs) -> dict[str, An Returns: dict[str, Any]: The raw response of the API. """ - body_payload = resolve_identity_detection_prepare_body_request(ids=ids, action_params_values=kwargs) + body_payload = resolve_detections_prepare_body_request(ids=ids, action_params_values=kwargs) return http_request(method='PATCH', url_suffix='/alerts/entities/alerts/v2', json=body_payload) def cs_falcon_resolve_identity_detection(args: dict[str, Any]) -> CommandResults: - """Command to resolve idenetiy detections. + """Command to resolve identity detections. + + Args: + args (dict[str, Any]): The arguments of the command. + + Returns: + CommandResults: The command results object. + """ + return handle_resolve_detections(args, 'IDP Detection(s) {} were successfully updated') + + +def cs_falcon_resolve_mobile_detection(args: dict[str, Any]) -> CommandResults: + """Command to resolve mobile detections. + + Args: + args (dict[str, Any]): The arguments of the command. + + Returns: + CommandResults: The command results object. + """ + return handle_resolve_detections(args, 'Mobile Detection(s) {} were successfully updated') + + +def handle_resolve_detections(args: dict[str, Any], hr_template: str) -> CommandResults: + """Handle the mobile & identity detections resolve commands. Args: args (dict[str, Any]): The arguments of the command. @@ -6465,10 +6550,10 @@ def cs_falcon_resolve_identity_detection(args: dict[str, Any]) -> CommandResults show_in_ui = args.get('show_in_ui', '') # We pass the arguments in the form of **kwargs, since we also need the arguments' names for the API, # and it easier to achieve that using **kwargs - resolve_identity_detection_request(ids=ids, update_status=update_status, assign_to_name=assign_to_name, - assign_to_uuid=assign_to_uuid, unassign=unassign, append_comment=append_comment, - add_tag=add_tag, remove_tag=remove_tag, show_in_ui=show_in_ui) - return CommandResults(readable_output=f'IDP Detection(s) {", ".join(ids)} were successfully updated') + resolve_detections_request(ids=ids, update_status=update_status, assign_to_name=assign_to_name, + assign_to_uuid=assign_to_uuid, unassign=unassign, append_comment=append_comment, + add_tag=add_tag, remove_tag=remove_tag, show_in_ui=show_in_ui) + return CommandResults(readable_output=hr_template.format(", ".join(ids))) def cs_falcon_list_users_command(args: dict[str, Any]) -> CommandResults: @@ -6748,7 +6833,6 @@ def main(): return_results(get_modified_remote_data_command(args)) elif command == 'update-remote-system': return_results(update_remote_system_command(args)) - elif demisto.command() == 'get-mapping-fields': return_results(get_mapping_fields_command()) elif command == 'cs-falcon-spotlight-search-vulnerability': @@ -6802,6 +6886,8 @@ def main(): return_results(cs_falcon_cspm_update_policy_settings_command(args=args)) elif command == 'cs-falcon-resolve-identity-detection': return_results(cs_falcon_resolve_identity_detection(args=args)) + elif command == 'cs-falcon-resolve-mobile-detection': + return_results(cs_falcon_resolve_mobile_detection(args=args)) elif command == 'cs-falcon-list-users': return_results(cs_falcon_list_users_command(args=args)) elif command == 'cs-falcon-get-incident-behavior': diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml index 05ca04031968..b77db3a6e1fd 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon.yml @@ -77,6 +77,12 @@ configuration: type: 0 section: Collect advanced: true +- display: Mobile Detections fetch query + name: mobile_detections_fetch_query + type: 0 + section: Collect + required: false + advanced: true - display: IOM fetch query name: iom_fetch_query type: 0 @@ -90,14 +96,13 @@ configuration: section: Collect required: false advanced: true - additionalinfo: "In the format: cloud_provider=aws&aws_account_id=1234. - The query must have the argument 'cloud_provider' configured. Multiple values for the same parameter is not supported. For more information, refer to the integration docs." + additionalinfo: "In the format: cloud_provider=aws&aws_account_id=1234. The query must have the argument 'cloud_provider' configured. Multiple values for the same parameter is not supported. For more information, refer to the integration docs." - display: Fetch incidents name: isFetch type: 8 - defaultvalue: 'true' section: Collect required: false + defaultvalue: 'true' - display: Incident type name: incidentType type: 13 @@ -121,42 +126,43 @@ configuration: section: Connect advanced: true required: false -- display: Use system proxy settings +- display: 'Use system proxy settings' name: proxy type: 8 section: Connect advanced: true required: false -- additionalinfo: When selected, closes the CrowdStrike Falcon incident or detection, which is mirrored in the Cortex XSOAR incident. - defaultvalue: 'false' +- defaultvalue: 'false' display: 'Close Mirrored XSOAR Incident' name: close_incident type: 8 section: Collect advanced: true required: false -- defaultvalue: 'false' + additionalinfo: When selected, closes the CrowdStrike Falcon incident or detection, which is mirrored in the Cortex XSOAR incident. +- additionalinfo: When selected, closes the Cortex XSOAR incident, which is mirrored in the CrowdStrike Falcon incident or detection, according to the types that were chosen to be fetched and mirrored. + defaultvalue: 'false' display: 'Close Mirrored CrowdStrike Falcon Incident or Detection' name: close_in_cs_falcon type: 8 section: Collect advanced: true required: false - additionalinfo: When selected, closes the Cortex XSOAR incident, which is mirrored in the CrowdStrike Falcon incident or detection, according to the types that were chosen to be fetched and mirrored. -- additionalinfo: Choose what to fetch - incidents, detections, IDP detections. You can choose any combination. - defaultvalue: 'Endpoint Detection' +- defaultvalue: 'Endpoint Detection' display: 'Fetch types' name: fetch_incidents_or_detections type: 16 section: Collect advanced: true required: false + additionalinfo: Choose what to fetch - incidents, detections, IDP detections. You can choose any combination. options: - IDP Detection - Endpoint Incident - Endpoint Detection - Indicator of Misconfiguration - Indicator of Attack + - Mobile Detection - defaultvalue: '1' display: 'Incidents Fetch Interval' name: incidentFetchInterval @@ -194,27 +200,27 @@ script: defaultValue: 0 - description: 'A comma-separated list of device IDs to limit the results.' name: ids - - auto: PREDEFINED - description: 'The status of the device. Possible values are: "Normal", "containment_pending", "contained", and "lift_containment_pending".' + - description: 'The status of the device. Possible values are: "Normal", "containment_pending", "contained", and "lift_containment_pending".' name: status + auto: PREDEFINED predefined: - 'normal' - containment_pending - contained - lift_containment_pending - - auto: PREDEFINED - description: 'The host name of the device.' + - description: 'The host name of the device.' name: hostname + auto: PREDEFINED predefined: - '' - description: 'The platform name of the device. Possible values are: Windows, Mac, and Linux.' name: platform_name auto: PREDEFINED predefined: - - Windows + - 'Windows' - Mac - Linux - - description: The site name of the device. + - description: 'The site name of the device.' name: site_name description: Searches for a device that matches the query. name: cs-falcon-search-device @@ -4716,8 +4722,45 @@ script: - 'false' - 'true' auto: PREDEFINED - description: Perform actions on alerts. + description: Perform actions on identity detection alerts. name: cs-falcon-resolve-identity-detection + - arguments: + - description: IDs of the alerts to update. + name: ids + isArray: true + required: true + - description: 'Assign the specified detections to a user based on their username.' + name: assign_to_name + - description: Assign the specified detections to a user based on their UUID. + name: assign_to_uuid + - description: Appends a new comment to any existing comments for the specified detections. + name: append_comment + - description: Add a tag to the specified detections. + name: add_tag + - description: Remove a tag from the specified detections. + name: remove_tag + - description: Update status of the alert to the specified value. + name: update_status + predefined: + - 'new' + - 'in_progress' + - 'closed' + - 'reopened' + auto: PREDEFINED + - description: Whether to unassign any assigned users to the specified detections. + name: unassign + predefined: + - 'false' + - 'true' + auto: PREDEFINED + - description: If true, displays the detection in the UI. + name: show_in_ui + predefined: + - 'false' + - 'true' + auto: PREDEFINED + description: Perform actions on mobile detection alerts. + name: cs-falcon-resolve-mobile-detection - arguments: - description: IDs (UUID) of specific users to list. name: id diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon_test.py b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon_test.py index 7175122bd68c..622b63c68abc 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon_test.py +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/CrowdStrikeFalcon_test.py @@ -85,9 +85,9 @@ def test_incident_to_incident_context(): assert res == incident_context -def test_idp_detectionin_to_incident_context(): - from CrowdStrikeFalcon import idp_detection_to_incident_context - res = idp_detection_to_incident_context(input_data.response_idp_detection.copy()) +def test_detection_to_incident_context(): + from CrowdStrikeFalcon import detection_to_incident_context + res = detection_to_incident_context(input_data.response_idp_detection.copy(), "IDP Detection") assert res == input_data.context_idp_detection @@ -2220,7 +2220,7 @@ def test_old_fetch_to_new_fetch(self, set_up_mocks, mocker): }) fetch_incidents() assert demisto.setLastRun.mock_calls[0][1][0] == [ - {'time': '2020-09-04T09:16:10Z'}, {'time': '2020-09-04T09:22:10Z'}, {}, {}, {}] + {'time': '2020-09-04T09:16:10Z'}, {'time': '2020-09-04T09:22:10Z'}, {}, {}, {}, {}] @freeze_time("2020-09-04T09:16:10Z") def test_new_fetch(self, set_up_mocks, mocker, requests_mock): @@ -4234,7 +4234,7 @@ def test_get_modified_remote_data_command(mocker): Given - arguments - lastUpdate time - raw incidents, detection, and idp_detection (results of get_incidents_ids, get_fetch_detections, - and get_idp_detections_ids) + and get_detections_ids) When - running get_modified_remote_data_command Then @@ -5919,12 +5919,12 @@ def test_http_request_arguments(self, mocker: MockerFixture): Then - Validate that the arguments are mapped correctly to the json body. """ - from CrowdStrikeFalcon import resolve_identity_detection_request + from CrowdStrikeFalcon import resolve_detections_request http_request_mocker = mocker.patch('CrowdStrikeFalcon.http_request') ids = ['1,2'] action_param_values = {'update_status': 'new', 'assign_to_name': 'bot'} action_params_http_body = [{'name': 'update_status', 'value': 'new'}, {'name': 'assign_to_name', 'value': 'bot'}] - resolve_identity_detection_request(ids=ids, **action_param_values) + resolve_detections_request(ids=ids, **action_param_values) assert http_request_mocker.call_args_list[0][1].get('json') == {'action_parameters': action_params_http_body, 'ids': ids} @@ -5943,6 +5943,21 @@ def test_resolve_identity_detection(self, mocker: MockerFixture): assert isinstance(command_results.readable_output, str) assert 'IDP Detection(s) 1, 2 were successfully updated' in command_results.readable_output + def test_resolve_mobile_detection(self, mocker: MockerFixture): + """ + Given: + - Arguments for the command. + When + - Calling the cs-falcon-resolve-mobile-detection command. + Then + - Validate the data of the CommandResults object returned. + """ + from CrowdStrikeFalcon import cs_falcon_resolve_mobile_detection + mocker.patch('CrowdStrikeFalcon.http_request', return_value=requests.Response()) + command_results = cs_falcon_resolve_mobile_detection(args={'ids': '1,2'}) + assert isinstance(command_results.readable_output, str) + assert 'Mobile Detection(s) 1, 2 were successfully updated' in command_results.readable_output + class TestIOAFetch: # Since this integration fetches multiple incidents, the last run object contains a list of diff --git a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md index 6fc72abeded4..24926ee14128 100644 --- a/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md +++ b/Packs/CrowdStrikeFalcon/Integrations/CrowdStrikeFalcon/README.md @@ -8,7 +8,7 @@ The CrowdStrike Falcon OAuth 2 API integration (formerly Falcon Firehose API), e | **Parameter** | **Description** | **Required** | | --- | --- | --- | - | Server URL (e.g., https://api.crowdstrike.com) | | True | + | Server URL (e.g., ) | | True | | Client ID | | True | | Secret | | True | | Source Reliability | Reliability of the source providing the intelligence data. Currently used for “CVE” reputation command. | False | @@ -135,6 +135,7 @@ Available parameters: Exmample: `cloud_provider=aws®ion=eu-west-2` More information about the parameters can be found [here](https://www.falconpy.io/Service-Collections/CSPM-Registration.html#keyword-arguments-13). + ### 1. Search for a device --- @@ -345,7 +346,7 @@ or by providing the IDs of the detections. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | | ids | The IDs of the detections to search. If provided, will override other arguments. | Optional | -| filter | Filter detections using a query in Falcon Query Language (FQL).
    For example, filter="device.hostname:'CS-SE-TG-W7-01'"
    For a full list of valid filter options, see: https://falcon.crowdstrike.com/support/documentation/2/query-api-reference#detectionsearch. | Optional | +| filter | Filter detections using a query in Falcon Query Language (FQL).
    For example, filter="device.hostname:'CS-SE-TG-W7-01'"
    For a full list of valid filter options, see: . | Optional | | extended_data | Whether to get additional data such as device and behaviors processed. Possible values are: Yes, No. | Optional | #### Context Output @@ -4780,7 +4781,7 @@ Get a list of ML exclusions by specifying their IDs, value, or a specific filter | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| filter | A custom filter by which the exclusions should be filtered.
    The syntax follows the pattern `<property>:[operator]'<value>'` for example: value:'test'.
    Available filters: applied_globally, created_by, created_on, last_modified, modified_by, value.
    For more information, see: https://www.falconpy.io/Service-Collections/Falcon-Query-Language. | Optional | +| filter | A custom filter by which the exclusions should be filtered.
    The syntax follows the pattern `<property>:[operator]'<value>'` for example: value:'test'.
    Available filters: applied_globally, created_by, created_on, last_modified, modified_by, value.
    For more information, see: . | Optional | | value | The value by which the exclusions should be filtered. | Optional | | ids | A comma-separated list of exclusion IDs to retrieve. The IDs overwrite the filter and value. | Optional | | limit | The maximum number of records to return. [1-500]. Applies only if the IDs argument is not supplied. | Optional | @@ -5102,7 +5103,7 @@ Get a list of IOA exclusions by specifying their IDs or a filter. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| filter | A custom filter by which the exclusions should be filtered.
    The syntax follows the pattern `<property>:[operator]'<value>'` for example: name:'test'.
    Available filters: applied_globally, created_by, created_on, name, last_modified, modified_by, value, pattern.
    For more information, see: https://www.falconpy.io/Service-Collections/Falcon-Query-Language. | Optional | +| filter | A custom filter by which the exclusions should be filtered.
    The syntax follows the pattern `<property>:[operator]'<value>'` for example: name:'test'.
    Available filters: applied_globally, created_by, created_on, name, last_modified, modified_by, value, pattern.
    For more information, see: . | Optional | | name | The name by which the exclusions should be filtered. | Optional | | ids | A comma-separated list of exclusion IDs to retrieve. The IDs overwrite the filter and name. | Optional | | limit | The limit of how many exclusions to retrieve. Default is 50. Applies only if the IDs argument is not supplied. | Optional | @@ -6241,8 +6242,11 @@ List identity entities. | CrowdStrike.CSPMPolicy.account_scope | String | The account scope. | #### Command example + ```!cs-falcon-cspm-list-policy-details policy_ids=1,2``` + #### Context Example + ```json { "CrowdStrike": { @@ -6355,6 +6359,7 @@ List identity entities. #### Human Readable Output >### CSPM Policy Details: + >|Id|Description|Policy Statement|Policy Remediation|Cloud Service Subtype|Cloud Platform Type|Cloud Service Type|Default Severity|Policy Type|Tactic|Technique| >|---|---|---|---|---|---|---|---|---|---|---| >| 1 | Because IAM access keys are long-term credentials, as time goes on, the risk of these keys being exposed is increased.

    Keys are often left on old servers, accidentally published through Git, or stolen from developer machines. The longer the keys are valid, the more likely they are to be discovered in one of these places. By ensuring keys are rotated at least every 90 days, you can be confident that if those keys are discovered, they cannot be abused. | IAM user access key active longer than 90 days | Step 1. From the AWS Console, navigate to the IAM page.\|
    Step 2. Locate and click on the offending IAM User.\|
    Step 3. Click on the Security Credentials tab.\|
    Step 4. Navigate to the Access Keys section and choose between making the access key inactive, deleting the key, or rotating the key. | Access Keys | aws | IAM | informational | Configuration | Credential Access | Steal Application Access Token | @@ -6418,8 +6423,11 @@ Returns information about current policy settings. | CrowdStrike.CSPMPolicySetting.attack_types | Array | The attack types. | #### Command example + ```!cs-falcon-cspm-list-service-policy-settings limit=2``` + #### Context Example + ```json { "CrowdStrike": { @@ -6558,6 +6566,7 @@ Returns information about current policy settings. #### Human Readable Output >### CSPM Policy Settings: + >|Policy Id|Is Remediable|Remediation Summary|Name|Policy Type|Cloud Service Subtype|Cloud Service|Default Severity| >|---|---|---|---|---|---|---|---| >| 1 | false | | EFS File System is encrypted without CMK | Configuration | N/A | efs | informational | @@ -6587,8 +6596,11 @@ Updates a policy setting - can be used to override policy severity or to disable #### Context Output There is no context output for this command. + #### Command example + ```!cs-falcon-cspm-update-policy_settings policy_id=1 enabled=true regions="eu-central-1,eu-central-2" severity=high tag_excluded=false``` + #### Human Readable Output >Policy 1 was updated successfully @@ -6596,7 +6608,7 @@ There is no context output for this command. ### cs-falcon-resolve-identity-detection *** -Perform actions on alerts. +Perform actions on identity detection alerts. #### Base Command @@ -6621,7 +6633,9 @@ Perform actions on alerts. There is no context output for this command. #### Command example + ```!cs-falcon-resolve-identity-detection ids="id_1,id_2" add_tag="Demo tag" append_comment="Demo comment" assign_to_name="morganf" show_in_ui=true update_status=in_progress``` + #### Human Readable Output >IDP Detection(s) id_1, id_2 were successfully updated @@ -6762,3 +6776,38 @@ Get IOA Rules for Custom IOA rule triggered detections | CrowdStrike.IOARules.ruletype_id | String | The IOA Rule's Rule Type ID. | | CrowdStrike.IOARules.ruletype_name | String | The IOA Rule's Rule Type Name. | | CrowdStrike.IOARules.version_ids | String | The IOA Rule's Version ID. | + +### cs-falcon-resolve-mobile-detection + +*** +Perform actions on mobile detection alerts. + +#### Base Command + +`cs-falcon-resolve-mobile-detection` + +#### Input + +| **Argument Name** | **Description** | **Required** | +| --- | --- | --- | +| ids | IDs of the alerts to update. | Required | +| assign_to_name | Assign the specified detections to a user based on their username. | Optional | +| assign_to_uuid | Assign the specified detections to a user based on their UUID. | Optional | +| append_comment | Appends a new comment to any existing comments for the specified detections. | Optional | +| add_tag | Add a tag to the specified detections. | Optional | +| remove_tag | Remove a tag from the specified detections. | Optional | +| update_status | Update status of the alert to the specified value. Possible values are: new, in_progress, closed, reopened. | Optional | +| unassign | Whether to unassign any assigned users to the specified detections. Possible values are: false, true. | Optional | +| show_in_ui | If true, displays the detection in the UI. Possible values are: false, true. | Optional | + +#### Context Output + +There is no context output for this command. + +#### Command example + +```!cs-falcon-resolve-mobile-detection ids="id_1,id_2" add_tag="Demo tag" append_comment="Demo comment" assign_to_name="morganf" show_in_ui=true update_status=in_progress``` + +#### Human Readable Output + +>Mobile Detection(s) id_1, id_2 were successfully updated \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_1.md b/Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_1.md new file mode 100644 index 000000000000..3875b09daaa7 --- /dev/null +++ b/Packs/CrowdStrikeFalcon/ReleaseNotes/1_13_1.md @@ -0,0 +1,47 @@ + +#### Classifiers + +##### CrowdStrike Falcon Incident Classifier + +- Added support for **CrowdStrike Falcon Mobile Detection**. + +#### Incident Fields + +- New: **CrowdStrike Falcon Security patch level** +- New: **CrowdStrike Falcon Firmware Build Fingerprint** +- New: **CrowdStrike Falcon Firmware Build Time** +- New: **CrowdStrike Falcon Mobile Manufacturer** +- New: **CrowdStrike Falcon Mobile platform version** +- New: **CrowdStrike Falcon Mobile Product** + +- Added the **CrowdStrike Falcon Mobile Detection** incident type to the following incident fields: + +- **Behaviour Objective** +- **Behaviour Scenario** +- **Behaviour Tactic** +- **CrowdStrike Falcon Crawled Timestamp** +- **CrowdStrike Falcon Detection Type** + +#### Incident Types + +- New: **CrowdStrike Falcon Mobile Detection** + + +#### Integrations + +##### CrowdStrike Falcon + +- Updated the Docker image to: *demisto/py3-tools:1.0.0.88283*. +- Added the new command ***cs-falcon-resolve-mobile-detection***. +- Added the **Mobile Detection** option to the **Fetch type** options. +- Added the **Mobile Detections fetch query** param to allow custom query for *Mobile Detection* **fetch-incidents**. +- Added support for mirroring for **CrowdStrike Falcon Mobile Detection** incident type. + +#### Mappers + +##### CrowdStrike Falcon Mapper + +- Added support for mirroring for **CrowdStrike Falcon Mobile Detection** incident type. + +##### CrowdStrike Falcon - Outgoing Mapper +- Added support for mirroring for **CrowdStrike Falcon Mobile Detection** incident type. \ No newline at end of file diff --git a/Packs/CrowdStrikeFalcon/pack_metadata.json b/Packs/CrowdStrikeFalcon/pack_metadata.json index 4fb1b22f31bd..7dcca08a926e 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.13.0", + "currentVersion": "1.13.1", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 0e366d8a67cf646e0f99131c7cbb2e0e5c77ce49 Mon Sep 17 00:00:00 2001 From: Moshe Eichler <78307768+MosheEichler@users.noreply.github.com> Date: Thu, 29 Feb 2024 23:28:44 +0200 Subject: [PATCH 115/272] Fix/[XSUP-33694]/GitHub-Collector/Fetch duplicates (#33090) * fix fetch github audit logs * test * revert * RN * docker image * RN * fix * add ut * docstring * add new line * CR fixes * revert * add * * RN * caned to 1000 * Bump pack from version GitHub to 2.0.30. * added new parameter * delete after and fix UT * revert name * doker --------- Co-authored-by: Content Bot --- .../GitHubEventCollector.py | 46 +++++++++++------- .../GitHubEventCollector.yml | 6 +-- .../GitHubEventCollector_test.py | 48 +++++++++++++++++-- .../GitHubEventCollector/README.md | 4 +- Packs/GitHub/ReleaseNotes/2_0_30.md | 8 ++++ Packs/GitHub/pack_metadata.json | 2 +- 6 files changed, 86 insertions(+), 28 deletions(-) create mode 100644 Packs/GitHub/ReleaseNotes/2_0_30.md diff --git a/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.py b/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.py index 331f4d5fe288..e6fed0fec722 100644 --- a/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.py +++ b/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.py @@ -9,21 +9,34 @@ urllib3.disable_warnings() VENDOR = 'github' PRODUCT = 'github-audit' +DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" def get_github_timestamp_format(value): - """Converting int(epoch), str(3 days) or datetime to github's api time""" - timestamp: Optional[datetime] = None + """Converts int(epoch), str(3 days), or datetime to GitHub's API time format. + + Args: + value (Any): The value to convert to GitHub's API time format. + + Returns: + str: The value in GitHub's API time format. + + Raises: + TypeError: If the input value is not a valid time. + """ if isinstance(value, int): - value = str(value) + value = datetime.utcfromtimestamp(value / 1000) + elif isinstance(value, str): + value = dateparser.parse(value) if not isinstance(value, datetime): - timestamp = dateparser.parse(value) - if timestamp is None: raise TypeError(f'after is not a valid time {value}') - timestamp_epoch = timestamp.timestamp() * 1000 - str_bytes = f'{timestamp_epoch}|'.encode('ascii') - base64_bytes = base64.b64encode(str_bytes) - return base64_bytes.decode('ascii') + + return f'created:>{value.strftime(DATETIME_FORMAT)}' + + +def prepare_demisto_params(params: dict): + params['phrase'] = params.get('after') + del params['after'] class GithubParams(BaseModel): @@ -32,9 +45,9 @@ class GithubParams(BaseModel): """ include: str order: str = 'asc' - after: str + phrase: str per_page: int = 100 # Maximum is 100 - _normalize_after = validator('after', pre=True, allow_reuse=True)( + _normalize_after = validator('phrase', pre=True, allow_reuse=True)( get_github_timestamp_format ) @@ -48,7 +61,7 @@ class GithubEventsRequestConfig(IntegrationHTTPRequest): class GithubClient(IntegrationEventsClient): def set_request_filter(self, after: str): if self.request.params: - self.request.params.after = get_github_timestamp_format(after) # type: ignore + self.request.params.phrase = get_github_timestamp_format(after) # type: ignore class GithubGetEvents(IntegrationGetEvents): @@ -68,7 +81,6 @@ def _iter_events(self) -> Generator: self.client.set_request_filter(last['@timestamp']) events = self.client.call(self.client.request).json() try: - events.pop(0) assert events except (IndexError, AssertionError): LOG('empty list, breaking') @@ -82,11 +94,7 @@ def get_last_run(events: List[dict]) -> dict: if not events: return demisto.getLastRun() last_timestamp = events[-1]['@timestamp'] - last_time = last_timestamp / 1000 - next_fetch_time = datetime.fromtimestamp(last_time) + timedelta( - seconds=1 - ) - return {'after': next_fetch_time.isoformat()} + return {'after': last_timestamp} def main(): @@ -99,6 +107,8 @@ def main(): 'Accept': 'application/vnd.github.v3+json'} demisto_params['headers'] = headers + + prepare_demisto_params(demisto_params) demisto_params['params'] = GithubParams(**demisto_params) request = GithubEventsRequestConfig(**demisto_params) diff --git a/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.yml b/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.yml index ad9785c08631..b2566a3889a4 100644 --- a/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.yml +++ b/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector.yml @@ -7,7 +7,7 @@ sectionOrder: name: Github Event Collector display: Github Event Collector category: Analytics & SIEM -description: Github logs event collector integration for XSIAM. +description: Github logs event collector integration for Cortex XSIAM. configuration: - display: Server URL (e.g. 'https://api.github.com/orgs/XXXXX/audit-log') name: url @@ -65,7 +65,7 @@ script: - arguments: - auto: PREDEFINED defaultValue: 'False' - description: Set this argument to True in orfer to create events, otherwise the command will only display them. + description: Set this argument to True in order to create events, otherwise the command will only display them. name: should_push_events predefined: - 'True' @@ -73,7 +73,7 @@ script: required: true description: Manual command to fetch events and display them. name: github-get-events - dockerimage: demisto/fastapi:1.0.0.86524 + dockerimage: demisto/fastapi:1.0.0.88462 isfetchevents: true subtype: python3 marketplaces: diff --git a/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector_test.py b/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector_test.py index 76fe2011f284..ad80720c1109 100644 --- a/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector_test.py +++ b/Packs/GitHub/Integrations/GitHubEventCollector/GitHubEventCollector_test.py @@ -1,5 +1,7 @@ - -from GitHubEventCollector import GithubGetEvents, demisto +import pytest +from freezegun import freeze_time +import datetime +from GitHubEventCollector import GithubGetEvents, get_github_timestamp_format, demisto def test_last_run(mocker): @@ -16,12 +18,50 @@ def test_last_run(mocker): """ # get some events - events = [{'@timestamp': 1619510400000}, {'@timestamp': 1619510400000}, {'@timestamp': 1619510400000}] + events = [{'@timestamp': 1619510200000}, {'@timestamp': 1619510300000}, {'@timestamp': 1619510400000}] last_run = GithubGetEvents.get_last_run(events) # make sure the last run is the last event in isoformat - assert last_run == {'after': '2021-04-27T08:00:01'} + assert last_run == {'after': 1619510400000} # now get no events, and make sure the last run is not changed mocker.patch.object(demisto, "getLastRun", return_value=last_run) assert GithubGetEvents.get_last_run([]) == last_run + + +@freeze_time('2021-11-15T00:00:00Z') +def test_get_github_timestamp_format(): + """ + Given: + - A time in few variations + When: + - Running thq get_github_timestamp_format function + Then: + - Ensure the output is in the form 'created:>--T::Z' + + Note: This test could fail locally because of timezone differences. Run it on a docker image. + """ + + # Test conversion of an int value (representing an epoch timestamp) + timestamp = 1636934400000 + result = get_github_timestamp_format(timestamp) + expected_result = 'created:>2021-11-15T00:00:00Z' + assert result == expected_result + + # Test conversion of a str value (representing a date string) + date_string = '3 days ago' + result = get_github_timestamp_format(date_string) + expected_result = 'created:>2021-11-12T00:00:00Z' + assert result == expected_result + + # Test conversion of a datetime object + datetime_object = datetime.datetime(2021, 11, 15, 12, 0, 0) + result = get_github_timestamp_format(datetime_object) + expected_result = 'created:>2021-11-15T12:00:00Z' + assert result == expected_result + + # Test that a TypeError is raised for an unsupported input type + unsupported_type = 'foo' + with pytest.raises(TypeError) as e: + get_github_timestamp_format(unsupported_type) + assert 'after is not a valid time' in e.value.args[0] diff --git a/Packs/GitHub/Integrations/GitHubEventCollector/README.md b/Packs/GitHub/Integrations/GitHubEventCollector/README.md index 4c9e29ca459b..c93d2f6dc56b 100644 --- a/Packs/GitHub/Integrations/GitHubEventCollector/README.md +++ b/Packs/GitHub/Integrations/GitHubEventCollector/README.md @@ -1,4 +1,4 @@ -Github logs event collector integration for XSIAM. +Github logs event collector integration for Cortex XSIAM. This integration was integrated and tested with Github REST API V3 ## Configure Github Event Collector on Cortex XSOAR @@ -33,7 +33,7 @@ Manual command to fetch events and display them. | **Argument Name** | **Description** | **Required** | | --- | --- | --- | -| should_push_events | Set this argument to True in orfer to create events, otherwise the command will only display them. Possible values are: True, False. Default is False. | Required | +| should_push_events | Set this argument to True in order to create events, otherwise the command will only display them. Possible values are: True, False. Default is False. | Required | #### Context Output diff --git a/Packs/GitHub/ReleaseNotes/2_0_30.md b/Packs/GitHub/ReleaseNotes/2_0_30.md new file mode 100644 index 000000000000..ecbd2631e24b --- /dev/null +++ b/Packs/GitHub/ReleaseNotes/2_0_30.md @@ -0,0 +1,8 @@ + +#### Integrations + +##### Github Event Collector + +- Updated the Docker image to: *demisto/fastapi:1.0.0.88462*. +- Fixed a bug that caused duplicates in the ***fetch-events*** command. +- The time format has been updated to be compatible with GitHub and GitHub enterprise. diff --git a/Packs/GitHub/pack_metadata.json b/Packs/GitHub/pack_metadata.json index 2bc01545c4f6..7603b71b0b66 100644 --- a/Packs/GitHub/pack_metadata.json +++ b/Packs/GitHub/pack_metadata.json @@ -2,7 +2,7 @@ "name": "GitHub", "description": "Manage GitHub issues and pull requests directly from Cortex XSOAR", "support": "xsoar", - "currentVersion": "2.0.29", + "currentVersion": "2.0.30", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From fc249f3f62d227133696a7ef391053ae24cb9bb7 Mon Sep 17 00:00:00 2001 From: Dan Tavori <38749041+dantavori@users.noreply.github.com> Date: Fri, 1 Mar 2024 00:37:57 +0200 Subject: [PATCH 116/272] to js (#33135) * to js * format * doc * fix --- .../ReleaseNotes/1_2_62.md | 10 +++ .../FiltersAndTransformers/Scripts/Cut/Cut.js | 17 +++++ .../FiltersAndTransformers/Scripts/Cut/Cut.py | 32 --------- .../Scripts/Cut/Cut.yml | 14 ++-- .../Scripts/Cut/Cut_test.py | 45 ------------ .../IsNotInCidrRanges/IsNotInCidrRanges.js | 3 + .../IsNotInCidrRanges/IsNotInCidrRanges.py | 72 ------------------- .../IsNotInCidrRanges/IsNotInCidrRanges.yml | 10 ++- .../IsNotInCidrRanges_test.py | 56 --------------- .../Scripts/IsNotInCidrRanges/README.md | 8 +-- .../FiltersAndTransformers/pack_metadata.json | 2 +- 11 files changed, 45 insertions(+), 224 deletions(-) create mode 100644 Packs/FiltersAndTransformers/ReleaseNotes/1_2_62.md create mode 100644 Packs/FiltersAndTransformers/Scripts/Cut/Cut.js delete mode 100644 Packs/FiltersAndTransformers/Scripts/Cut/Cut.py delete mode 100644 Packs/FiltersAndTransformers/Scripts/Cut/Cut_test.py create mode 100644 Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.js delete mode 100644 Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.py delete mode 100644 Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges_test.py diff --git a/Packs/FiltersAndTransformers/ReleaseNotes/1_2_62.md b/Packs/FiltersAndTransformers/ReleaseNotes/1_2_62.md new file mode 100644 index 000000000000..f8e2738c0bc9 --- /dev/null +++ b/Packs/FiltersAndTransformers/ReleaseNotes/1_2_62.md @@ -0,0 +1,10 @@ + +#### Scripts + +##### Cut + +- Improved implementation for better performance. + +##### IsNotInCidrRanges + +- Improved implementation for better performance. \ No newline at end of file diff --git a/Packs/FiltersAndTransformers/Scripts/Cut/Cut.js b/Packs/FiltersAndTransformers/Scripts/Cut/Cut.js new file mode 100644 index 000000000000..ebc768c05075 --- /dev/null +++ b/Packs/FiltersAndTransformers/Scripts/Cut/Cut.js @@ -0,0 +1,17 @@ +function cut(value, fields, delim) { + if (delim === "''") { + delim = ""; + } + + const data = value.split(delim); + fields = fields.split(",").map(num => parseInt(num, 10)); + + const maxIndex = Math.max(...fields); + if (data.length < maxIndex) { + throw new Error(`Invalid field index ${maxIndex}, should be between 1 to ${data.length}.`); + } + + return fields.map(i => data[i - 1]).join(delim); +} + +return cut(args.value, args.fields, args.delimiter); \ No newline at end of file diff --git a/Packs/FiltersAndTransformers/Scripts/Cut/Cut.py b/Packs/FiltersAndTransformers/Scripts/Cut/Cut.py deleted file mode 100644 index e959c7806fdc..000000000000 --- a/Packs/FiltersAndTransformers/Scripts/Cut/Cut.py +++ /dev/null @@ -1,32 +0,0 @@ -import demistomock as demisto # noqa: F401 -from CommonServerPython import * # noqa: F401 - - -def cut(value, fields, delim): - - if delim == "''": - delim = "" - - data = value.split(delim) - fields = [int(_) for _ in fields.split(",")] - - max_index = max(fields) - if len(data) < max_index: - raise Exception("Invalid field index {}, should be between 1 to {}.".format(max_index, len(data))) - - return delim.join([str(data[i - 1]) for i in fields]) - - -def main(): - try: - args = demisto.args() - value = args.get("value") - fields = args.get("fields") - delim = args.get("delimiter") - return_results(cut(value, fields, delim)) - except Exception as e: - return_error(f'Failed to execute Cut. Error: {str(e)}', e) - - -if __name__ in ('__main__', '__builtin__', 'builtins'): - main() diff --git a/Packs/FiltersAndTransformers/Scripts/Cut/Cut.yml b/Packs/FiltersAndTransformers/Scripts/Cut/Cut.yml index 6c4010f7f8c9..ac36e5d39730 100644 --- a/Packs/FiltersAndTransformers/Scripts/Cut/Cut.yml +++ b/Packs/FiltersAndTransformers/Scripts/Cut/Cut.yml @@ -3,12 +3,11 @@ commonfields: version: -1 name: Cut script: '' -type: python -subtype: python3 +type: javascript tags: - transformer - string -comment: | +comment: |- Cut a string by delimiter and return specific fields. Example ================= @@ -16,22 +15,21 @@ comment: | delimiter: "-" fields: "1,5" - return: "A-E" + return: "A-E". enabled: true args: - name: value required: true - description: Value to split + description: Value to split. - name: delimiter required: true - description: Delimiter to cut the string by. Pass '' to set delimiter to be empty string + description: Delimiter to cut the string by. Pass '' to set delimiter to be empty string. - name: fields required: true - description: 'Comma separated field numbers (e.g.: 1,5,7)' + description: 'Comma separated field numbers (e.g.: 1,5,7).' isArray: true scripttarget: 0 runas: DBotWeakRole tests: - CutTransformerTest fromversion: 5.0.0 -dockerimage: demisto/python3:3.10.13.86272 diff --git a/Packs/FiltersAndTransformers/Scripts/Cut/Cut_test.py b/Packs/FiltersAndTransformers/Scripts/Cut/Cut_test.py deleted file mode 100644 index a79e07b55184..000000000000 --- a/Packs/FiltersAndTransformers/Scripts/Cut/Cut_test.py +++ /dev/null @@ -1,45 +0,0 @@ -from Cut import cut - -import pytest -import demistomock as demisto -from Cut import main - - -@pytest.mark.parametrize('value,delimiter,fields,expected', [ - ('A-B-C-D-E', '-', '1,5', 'A-E'), - ('a,ב,c', ',', '2,3', 'ב,c'), -]) -def test_cut(value, delimiter, fields, expected): - """ - Given: - Case 1: A-B-C-D-E to split by - from char 1 to 5 - Case 2: a,ב,c to split by , from char 2 to 3 - - When: - Running Cut - - Then: - Case 1: Ensure A-E is returned - Case 2: Ensure ב,c is returned - """ - assert cut(value, fields, delimiter) == expected - - -@pytest.mark.parametrize('args, expected', [ - ({'value': 'a,ב,c', 'delimiter': ',', 'fields': '2,3'}, 'ב,c'), -]) -def test_cut_main(mocker, args, expected): - """ - Given: - a,ב,c to split by , from char 2 to 3. - When: - Running Cut script. - Then: - demisto.results called. - """ - mocker.patch.object(demisto, 'args', return_value=args) - mocker.patch.object(demisto, 'results') - main() - assert demisto.results.call_count == 1 - results = demisto.results.call_args[0][0] - assert results == expected diff --git a/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.js b/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.js new file mode 100644 index 000000000000..9f70c9cf19ac --- /dev/null +++ b/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.js @@ -0,0 +1,3 @@ +var res = executeCommand("IsInCidrRanges", args); +res = Array.isArray(res) ? res : [res]; +return res.map(val => val.Contents == "True" ? "False" : "True"); \ No newline at end of file diff --git a/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.py b/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.py deleted file mode 100644 index ed29d6884d44..000000000000 --- a/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.py +++ /dev/null @@ -1,72 +0,0 @@ -import demistomock as demisto # noqa: F401 -from CommonServerPython import * # noqa: F401 - - -import ipaddress - - -def validate_cidr(cidr: str) -> bool: - """ - Validates if the input string is in CIDR format. - - Args: - cidr (str): The string to be validated. - - Returns: - bool: True if the string is a valid CIDR, False otherwise. - - Raises: - ValueError: If the string is not a valid CIDR. - """ - try: - ipaddress.ip_network(cidr) - - except ValueError as e: - demisto.debug(f'Skipping "{cidr}": {e}') - return False - - return True - - -def process_ips(ip_addresses: list[str], cidr_range_list: list[str]) -> bool: - """ - Check if given IP (or IPs) address is part of a given CIDR (or a list of CIDRs). - - Args: - ip_addresses (List[str]): A list of IPs/IPv6s - cidr_range_list (List[str]): A list of CIDRs to be checked against. - - Returns: - bool: True if given IP is part of given CIDR range. - """ - not_in_range_list = [] - for ip in ip_addresses: - try: - ip_address = ipaddress.ip_address(ip) - except ValueError as e: - demisto.debug(f'Skipping "{ip}": {e}') - continue - - not_in_range_list.append( - all( - ip_address not in ipaddress.ip_network(cidr) - for cidr in cidr_range_list - if validate_cidr(cidr) - ) - ) - - return all(not_in_range_list) - - -def main(): # pragma: no cover - ip_addresses = argToList(demisto.args()["left"]) - cidr_range_list = argToList(demisto.args()["right"]) - - try: - return_results(process_ips(ip_addresses, cidr_range_list)) - except Exception as e: - return_error(f"Failed to execute IsNotInCidrRange. Error: {str(e)}") - - -if __name__ in ("__main__", "__builtin__", "builtins"): - main() diff --git a/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.yml b/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.yml index 5e1e29e17b7b..0202beb4ee1d 100644 --- a/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.yml +++ b/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges.yml @@ -3,23 +3,21 @@ commonfields: version: -1 name: IsNotInCidrRanges script: '' -type: python -subtype: python3 +type: javascript tags: - filter -comment: Checks whether an IPv4 address is not contained in one or more comma-delimited CIDR ranges. +comment: Checks whether an IPv4 or IPv6 address is not contained in one or more comma-delimited CIDR ranges. enabled: true args: - name: left required: true - description: A comma-separated list of IPv4 addresses to check. + description: A comma-separated list of IPv4/IPv6 addresses to check. isArray: true - name: right required: true - description: A comma-separated list of IPv4 ranges in CIDR notation against which to match. + description: A comma-separated list of IPv4/IPv6 ranges in CIDR notation against which to match. isArray: true scripttarget: 0 -dockerimage: demisto/python3:3.10.13.87159 runas: DBotWeakRole tests: - TestIsNotInCidrRanges diff --git a/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges_test.py b/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges_test.py deleted file mode 100644 index 6d81cc1f4d0a..000000000000 --- a/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/IsNotInCidrRanges_test.py +++ /dev/null @@ -1,56 +0,0 @@ -from pytest_mock import MockerFixture -from IsNotInCidrRanges import validate_cidr, process_ips - - -def test_validate_cidr(mocker: MockerFixture) -> None: - """ - Given - a CIDR string, - When - the validate_cidr function is called, - Then - it should return True if the string is a valid CIDR, and False otherwise. - """ - mocker.patch('IsNotInCidrRanges.demisto.debug', return_value=None) - assert validate_cidr('192.168.1.0/24') is True - assert validate_cidr('192.168.1.500/24') is False - - -def test_process_ips_ip_in_cidr() -> None: - """ - Given - a valid IP and CIDR range - When - the process_ips function is called - Then - it should return False as the IP is in the CIDR range. - """ - result = process_ips(['10.0.0.1'], ['10.0.0.0/8']) - assert result is False - - -def test_process_ips_ip_not_in_cidr() -> None: - """ - Given - a valid IP and CIDR range, - When - the process_ips function is called, - Then - it should return True as the IP is not in the CIDR range. - """ - result = process_ips(['172.16.0.1'], ['10.0.0.0/8']) - assert result is True - - -def test_process_ips_invalid_ip(mocker: MockerFixture) -> None: - """ - Given - an invalid IP and a valid CIDR range, - When - the process_ips function is called, - Then - it should skip the invalid IP and not raise an exception. - """ - mocker.patch('ipaddress.ip_address', side_effect=ValueError('Invalid IP')) - result = process_ips(['invalid_ip'], ['10.0.0.0/8']) - assert result is True diff --git a/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/README.md b/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/README.md index 0ede7afe9b02..9f6220f357f2 100644 --- a/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/README.md +++ b/Packs/FiltersAndTransformers/Scripts/IsNotInCidrRanges/README.md @@ -1,4 +1,4 @@ -Checks whether an IPv4 address is not contained in one or more comma-delimited CIDR ranges. +Checks whether an IPv4 or IPv6 address is not contained in one or more comma-delimited CIDR ranges. ## Script Data @@ -6,7 +6,7 @@ Checks whether an IPv4 address is not contained in one or more comma-delimited C | **Name** | **Description** | | --- | --- | -| Script Type | python3 | +| Script Type | javascript | | Tags | filter | | Cortex XSOAR Version | 5.0.0 | @@ -16,8 +16,8 @@ Checks whether an IPv4 address is not contained in one or more comma-delimited C | **Argument Name** | **Description** | | --- | --- | -| left | IPv4 address to filter. | -| right | Comma-separated list of IPv4 ranges in CIDR notation against which to match. | +| left | IPv4/IPv6 address to filter. | +| right | Comma-separated list of IPv4/IPv6 ranges in CIDR notation against which to match. | ## Outputs diff --git a/Packs/FiltersAndTransformers/pack_metadata.json b/Packs/FiltersAndTransformers/pack_metadata.json index 32a16f933fab..ef6253b5a779 100644 --- a/Packs/FiltersAndTransformers/pack_metadata.json +++ b/Packs/FiltersAndTransformers/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Filters And Transformers", "description": "Frequently used filters and transformers pack.", "support": "xsoar", - "currentVersion": "1.2.61", + "currentVersion": "1.2.62", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 22fac6b126d37625dfa439c874264eb8d37233e0 Mon Sep 17 00:00:00 2001 From: Dan Sterenson <38375556+dansterenson@users.noreply.github.com> Date: Sun, 3 Mar 2024 09:13:25 +0200 Subject: [PATCH 117/272] Added XSOAR linter to pre-commit (#32302) * updated pre-commit config template * Add static args to xsoar-linter pre-commit hook * Added static fields * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit * test pre-commit with logs * test pre-commit with error logs * test pre-commit with error logs * test pre-commit with error logs * test pre-commit with error logs * test pre-commit with error logs * test pre-commit with error logs * test * test * test * rollback code * rollback code * rollback code * test * rollback code * rollback code * lint fix --- .pre-commit-config_template.yaml | 8 ++++++++ Packs/Base/ReleaseNotes/1_33_36.md | 6 ++++++ .../Base/Scripts/CommonServerPython/CommonServerPython.py | 2 +- Packs/Base/pack_metadata.json | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 Packs/Base/ReleaseNotes/1_33_36.md diff --git a/.pre-commit-config_template.yaml b/.pre-commit-config_template.yaml index b872798e1c5e..456134a130dd 100644 --- a/.pre-commit-config_template.yaml +++ b/.pre-commit-config_template.yaml @@ -58,6 +58,14 @@ repos: - community - repo: local hooks: + - id: xsoar-lint + name: xsoar-lint + description: Run xsoar-linter on the code in content packs + entry: demisto-sdk xsoar-lint + files: ^Packs\/.*\.py$ + exclude: _test\.py|\.vulture_whitelist\.py|test_data|tests_data|TestData + require_serial: true + language: system - id: pylint-in-docker name: pylint-in-docker description: Run pylint on the code in content packs diff --git a/Packs/Base/ReleaseNotes/1_33_36.md b/Packs/Base/ReleaseNotes/1_33_36.md new file mode 100644 index 000000000000..4b18832581ad --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_33_36.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### CommonServerPython + +- Added ignore to sleep method to satisfy linters. diff --git a/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py b/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py index 1d636774f7c8..fec4b76db7d0 100644 --- a/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py +++ b/Packs/Base/Scripts/CommonServerPython/CommonServerPython.py @@ -9448,7 +9448,7 @@ def set_to_integration_context_with_retries(context, object_keys=None, sync=True ''.format(version, str(ve), CONTEXT_UPDATE_RETRY_TIMES - attempt)) # Sleep for a random time time_to_sleep = randint(1, 100) / 1000 - time.sleep(time_to_sleep) + time.sleep(time_to_sleep) # pylint: disable=E9003 def get_integration_context_with_version(sync=True): diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index c96905e352c6..51148d68c8ae 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.33.35", + "currentVersion": "1.33.36", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", From 422a48159e978f1e1c88e0de4732db5ab222a7a1 Mon Sep 17 00:00:00 2001 From: michal-dagan <109464765+michal-dagan@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:28:59 +0200 Subject: [PATCH 118/272] update send-mail (#33136) --- .../Integrations/MicrosoftGraphMail/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packs/MicrosoftGraphMail/Integrations/MicrosoftGraphMail/README.md b/Packs/MicrosoftGraphMail/Integrations/MicrosoftGraphMail/README.md index c0da222c6364..b02c2573c254 100644 --- a/Packs/MicrosoftGraphMail/Integrations/MicrosoftGraphMail/README.md +++ b/Packs/MicrosoftGraphMail/Integrations/MicrosoftGraphMail/README.md @@ -514,7 +514,7 @@ Creates a draft message in the specified user's mailbox. *** Sends an email using Microsoft Graph. - +Note: The *from* argument needs to be specified when the *Email address from which to fetch incidents* parameter is missing. #### Base Command From 6b2510463e6105efe972803237c17b35f43647b9 Mon Sep 17 00:00:00 2001 From: Dan Tavori <38749041+dantavori@users.noreply.github.com> Date: Sun, 3 Mar 2024 11:43:14 +0200 Subject: [PATCH 119/272] move GetIncidentsByQuery to api module (#33028) * moving to apimodule * increase coverage * guardrails * fix * Bump pack from version Base to 1.33.36. * deprecate includeContext arg * docker * Bump pack from version Base to 1.33.37. * docker --------- Co-authored-by: Content Bot --- .../GetIncidentsApiModule.py | 228 +++++++++++++++ .../GetIncidentsApiModule.yml | 16 ++ .../GetIncidentsApiModule_test.py | 266 ++++++++++++++++++ Packs/Base/ReleaseNotes/1_33_37.md | 18 ++ .../DBotFindSimilarIncidents.py | 84 +++--- .../DBotFindSimilarIncidents.yml | 2 +- .../DBotFindSimilarIncidents_test.py | 78 +++-- .../DBotFindSimilarIncidentsByIndicators.py | 10 +- .../DBotFindSimilarIncidentsByIndicators.yml | 2 +- ...otFindSimilarIncidentsByIndicators_test.py | 16 +- .../GetIncidentsByQuery.py | 263 ++--------------- .../GetIncidentsByQuery.yml | 7 +- .../GetIncidentsByQuery_test.py | 255 +++++------------ .../Scripts/GetIncidentsByQuery/README.md | 2 +- Packs/Base/pack_metadata.json | 2 +- 15 files changed, 728 insertions(+), 521 deletions(-) create mode 100644 Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule.py create mode 100644 Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule.yml create mode 100644 Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule_test.py create mode 100644 Packs/Base/ReleaseNotes/1_33_37.md diff --git a/Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule.py b/Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule.py new file mode 100644 index 000000000000..5698fa3baf60 --- /dev/null +++ b/Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule.py @@ -0,0 +1,228 @@ +from CommonServerPython import * + +DEFAULT_LIMIT = 500 +DEFAULT_PAGE_SIZE = 100 +DEFAULT_TIME_FIELD = "created" + + +def build_query_parameter( + custom_query: str | None, + incident_types: list[str], + time_field: str, + from_date: str | None, + to_date: str | None, + non_empty_fields: list[str], +) -> str: + """Builds the query parameter string from given arguments. + + Args: + custom_query (str | None): A custom query. + incident_types (list[str] | None): Incident types to retrieve. + time_field (str): The relevant time field to search by. + from_date (str | None): The start date for the incidents query. + to_date (str | None): The end date for the incidents query. + non_empty_fields (list[str]): Required non-empty incident fields. + + Raises: + Exception: If no query parts were added. + + Returns: + str: The query string built from the given arguments. + """ + query_parts = [] + if custom_query: + query_parts.append(custom_query) + if incident_types: + types = [x if "*" in x else f'"{x}"' for x in incident_types] + query_parts.append(f"type:({' '.join(types)})") + if from_date and time_field: + query_parts.append(f'{time_field}:>="{from_date}"') + if to_date and time_field: + query_parts.append(f'{time_field}:<"{to_date}"') + if non_empty_fields: + query_parts.append(" and ".join(f"{x}:*" for x in non_empty_fields)) + if not query_parts: + raise DemistoException("Incidents query is empty - please fill at least one argument") + return " and ".join(f"({x})" for x in query_parts) + + +def format_incident(inc: dict, fields_to_populate: list[str], include_context: bool) -> dict: + """Flattens custom fields with incident data and filters by fields_to_populate + + Args: + inc (dict): An incident. + fields_to_populate (list[str]): List of fields to populate. + include_context (bool): Whether or not to enrich the incident with its context data. + + Returns: + dict: The formatted incident. + """ + custom_fields = inc.pop('CustomFields', {}) + inc.update(custom_fields or {}) + if fields_to_populate: + inc = {k: v for k, v in inc.items() if k.lower() in {val.lower() for val in fields_to_populate}} + if any(f.lower() == "customfields" for f in fields_to_populate): + inc["CustomFields"] = custom_fields + if include_context: + inc['context'] = execute_command("getContext", {"id": inc["id"]}, extract_contents=True) + return inc + + +def get_incidents_with_pagination( + query: str, + from_date: str | None, + to_date: str | None, + fields_to_populate: list[str], + include_context: bool, + limit: int, + page_size: int, + sort: str, +) -> list[dict]: + """Performs paginated getIncidents requests until limit is reached or no more results. + Each incident in the response is formatted before returned. + + Args: + query (str): The incidents query string. + from_date (str | None): The fromdate argument for the incidents query. + to_date (str | None): The todate argument for the incidents query. + fields_to_populate (list[str]): The fields to populate for each incident. + include_context (bool): Whether or not to enrich the returned incidents with their the context data. + limit (int): Maximum number of incidents to return. + page_size (int): Number of incidents to retrieve per page. + sort (str): Sort order for incidents. + + Returns: + list[dict]: The requested incidents. + """ + incidents: list = [] + page = -1 + populate_fields = ",".join(f.split(".")[0] for f in fields_to_populate) + demisto.debug(f"Running getIncidents with {query=}") + while len(incidents) < limit: + page += 1 + page_results = execute_command( + "getIncidents", + args={ + "query": query, + "fromdate": from_date, + "todate": to_date, + "page": page, + "populateFields": populate_fields, + "size": page_size, + "sort": sort, + }, + extract_contents=True, + fail_on_error=True, + ).get('data') or [] + incidents += page_results + if len(page_results) < page_size: + break + return [ + format_incident(inc, fields_to_populate, include_context) + for inc in incidents[:limit] + ] + + +def prepare_fields_list(fields_list: list[str] | None) -> list[str]: + """Removes `incident.` prefix from the fields list and returns a list of unique values. + + Args: + fields_list (list[str] | None): The current state of the fields list, as provided by the user. + + Returns: + list[str]: The prepared fields list. + """ + return list({ + field.removeprefix("incident.") for field in fields_list if field + }) if fields_list else [] + + +def get_incidents( + custom_query: str | None = None, + incident_types: list[str] | None = None, + populate_fields: list[str] | None = None, + non_empty_fields: list[str] | None = None, + time_field: str = DEFAULT_TIME_FIELD, + from_date: datetime | None = None, + to_date: datetime | None = None, + include_context: bool = False, + limit: int = DEFAULT_LIMIT, + page_size: int = DEFAULT_PAGE_SIZE, +) -> list[dict]: + """Performs a deeper formatting on the search arguments and runs paginated incidents search. + + Args: + custom_query (str | None, optional): A custom query. Defaults to None. + incident_types (list[str] | None, optional): Incident types to retrieve. Defaults to None. + populate_fields (list[str] | None, optional): Incident fields to populate. Defaults to None. + non_empty_fields (list[str] | None, optional): Required non-empty incident fields. Defaults to None. + from_date (datetime | None, optional): The start date of the timeframe. Defaults to None. + to_date (datetime | None, optional): The end date of the timeframe. Defaults to None. + time_field (str, optional): The relevant time field to search by. Defaults to "created". + include_context (bool, optional): Whether or not to enrich the returned incidents with their the context data. + Defaults to False. + limit (int, optional): The search limit. Defaults to 500. + page_size (int, optional): Maximal page size. Defaults to 100. + + Returns: + list[dict]: The requested incidents. + """ + non_empty_fields = prepare_fields_list(non_empty_fields) + + if populate_fields := prepare_fields_list(populate_fields): + populate_fields.extend(non_empty_fields + ["id"]) + populate_fields = list(set(populate_fields)) + + query = build_query_parameter( + custom_query, + incident_types or [], + time_field, + from_date.isoformat() if from_date and time_field != "created" else None, + to_date.isoformat() if to_date and time_field != "created" else None, + non_empty_fields, + ) + + return get_incidents_with_pagination( + query, + from_date.astimezone().isoformat() if from_date and time_field == "created" else None, + to_date.astimezone().isoformat() if to_date and time_field == "created" else None, + populate_fields, + include_context, + limit, + page_size=min(limit, page_size), + sort=f"{time_field}.desc", + ) + + +def get_incidents_by_query(args: dict) -> list[dict]: + """Performs an initial parsing of args and calls the get_incidents method. + + Args: + args (dict): the GetIncidentsByQuery arguments. + + Returns: + list[dict]: The requested incidents. + """ + query = args.get("query") + incident_types = argToList(args.get("incidentTypes"), transform=str.strip) + populate_fields = argToList(args.get("populateFields"), transform=str.strip) + non_empty_fields = argToList(args.get("NonEmptyFields"), transform=str.strip) + time_field = args.get("timeField") or DEFAULT_TIME_FIELD + from_date = arg_to_datetime(args.get("fromDate")) + to_date = arg_to_datetime(args.get("toDate")) + include_context = argToBoolean(args.get("includeContext") or False) + limit = arg_to_number(args.get("limit")) or DEFAULT_LIMIT + page_size = arg_to_number(args.get("pageSize")) or DEFAULT_PAGE_SIZE + + return get_incidents( + query, + incident_types, + populate_fields, + non_empty_fields, + time_field, + from_date, + to_date, + include_context, + limit, + page_size, + ) diff --git a/Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule.yml b/Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule.yml new file mode 100644 index 000000000000..67f64d063482 --- /dev/null +++ b/Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule.yml @@ -0,0 +1,16 @@ +comment: Common code that is appended into scripts which require searching incidents. +commonfields: + id: GetIncidentsApiModule + version: -1 +name: GetIncidentsApiModule +script: '-' +subtype: python3 +tags: +- infra +- server +timeout: 0s +type: python +dockerimage: demisto/python3:3.10.12.66339 +tests: +- No Tests +fromversion: 5.0.0 diff --git a/Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule_test.py b/Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule_test.py new file mode 100644 index 000000000000..42f5849c6d43 --- /dev/null +++ b/Packs/ApiModules/Scripts/GetIncidentsApiModule/GetIncidentsApiModule_test.py @@ -0,0 +1,266 @@ +import pytest +from GetIncidentsApiModule import * + + +def mock_incident( + inc_id: int, + inc_type: str, + created: str, + modified: str, + **kwargs, +) -> dict: + # helper method for creating mock incidents + return { + "id": inc_id, + "name": f"This is incident {inc_id}", + "type": inc_type, + "severity": 0, + "status": 1, + "created": created, + "modified": modified, + "CustomFields": { + "testField": "testValue" + }, + "closed": "0001-01-01T00:00:00Z", + "labels": [{"type": "subject", "value": "This subject1"}, {"type": "unique", "value": "This subject1"}], + "attachment": [{"name": "Test word1 word2"}], + } | kwargs + + +INCIDENTS_LIST = [ + mock_incident(1, "Phishing", "2019-01-02T00:00:00Z", "2020-01-02T00:00:00Z"), + mock_incident(2, "Phishing", "2019-02-02T00:00:00Z", "2020-02-02T00:00:00Z"), + mock_incident(3, "Malware", "2020-02-02T00:00:00Z", "2020-02-02T00:00:00Z"), + mock_incident(4, "Malware", "2021-02-02T00:00:00Z", "2021-02-02T00:00:00Z"), + mock_incident(5, "Malware", "2021-02-02T00:00:00Z", "2021-02-02T00:00:00Z"), + mock_incident(6, "Unclassified", "2021-02-02T00:00:00Z", "2021-02-02T00:00:00Z"), + mock_incident(7, "Unclassified", "2021-02-02T00:00:00Z", "2021-02-02T00:00:00Z"), +] + + +def does_incident_match_query( + inc: dict, + time_field: str, + from_date_str: str, + to_date_str: str, + incident_types: list[str], +) -> bool: + # a helper method for mock_execute_command() that determines + # whether an incident should be part of the response + if not incident_types or inc["type"] in incident_types: + inc_time_field = dateparser.parse(inc[time_field]) + from_date = dateparser.parse(from_date_str or inc[time_field]) + to_date = dateparser.parse(to_date_str or inc[time_field]) + return from_date <= inc_time_field < to_date + return False + + +def mock_execute_command(command: str, args: dict) -> list[dict]: + # Mock implementations for `getIncidents` and `getContext` builtin commands. + match command: + case "getIncidents": + page = args["page"] + size = args["size"] + query = args["query"] or "" + incident_types = [] + time_field = "modified" if "modified" in query else "created" + from_date = args["fromdate"] + to_date = args["todate"] + # populate_fields = args["populateFields"] or [] + + if match := re.search(r"\(modified:>=\"([^\"]*)\"\)", query): + from_date = match.group(1) + if match := re.search(r"\(modified:<\"([^\"]*)\"\)", query): + to_date = match.group(1) + if match := re.search(r"\(type:\(([^)]*)\)\)", query): + incident_types = argToList(match.group(1), separator=" ", transform=lambda t: t.strip("\"")) + res = [ + i # {k: v for k, v in i.items() if not populate_fields or k in populate_fields} + for i in INCIDENTS_LIST + if does_incident_match_query(i, time_field, from_date, to_date, incident_types) + ][page * size:(page + 1) * size] + return [{"Contents": {"data": res}, "Type": "json"}] + case "getContext": + return [{"Contents": "context", "Type": "json"}] + case _: + raise Exception(f"Unmocked command: {command}") + + +def test_prepare_fields_list(): + """ + Given: A list of incident fields + When: Running prepare_fields_list() + Then: Ensure a unique list of fields without the `incident.` prefix for each item is returned + """ + assert prepare_fields_list(["incident.hello", "", "hello"]) == ["hello"] + + +def test_build_query(): + """ + Given: Different query arguments + When: Running build_query_parameter() + Then: Ensure the result is a query string in the expected format + """ + query = build_query_parameter( + custom_query="Extra part", + incident_types=["*phish*", "Malware"], + time_field="modified", + from_date="2019-01-10T00:00:00", + to_date="2019-01-12T00:00:00", + non_empty_fields=["status", "closeReason"], + ) + assert query == ( + "(Extra part) and (type:(*phish* \"Malware\")) and (modified:>=\"2019-01-10T00:00:00\") " + "and (modified:<\"2019-01-12T00:00:00\") and (status:* and closeReason:*)" + ) + + +def test_build_query_bad(): + """ + Given: No query arguments + When: Running build_query_parameter() + Then: Ensuring a DemistoException is raised + """ + with pytest.raises(DemistoException): + build_query_parameter( + custom_query=None, + incident_types=[], + time_field=None, + from_date=None, + to_date=None, + non_empty_fields=[], + ) + + +def test_get_incidents_by_query_sanity_test(mocker): + """ + Given: + - A mock incidents database (INCIDENTS_LIST) + - Search incidents query arguments + When: Running get_incidents_by_query() + Then: Ensure the expected 4 incidents are returned + """ + mocker.patch.object(demisto, "executeCommand", side_effect=mock_execute_command) + args = { + "incidentTypes": "Phishing,Malware", + "timeField": "created", + "fromDate": "2019-02-01T00:00:00", + "toDate": "3 days ago", + "limit": "10", + "includeContext": "false", + "pageSize": "10", + } + results = get_incidents_by_query(args) + assert len(results) == 4 + assert all( + inc["type"] in args["incidentTypes"] for inc in results + ) + assert all( + dateparser.parse(args["fromDate"]).astimezone() <= dateparser.parse(inc["created"]) + for inc in results + ) + assert all( + dateparser.parse(inc["created"]) < dateparser.parse(args["toDate"]).astimezone() + for inc in results + ) + + +def test_get_incidents_by_query_with_pagination(mocker): + """ + Given: + - A mock incidents database (INCIDENTS_LIST) + - Search incidents query arguments that should return 4 incidents (same as the sanity test) + When: + - pageSize is 3 + Then: + - Ensure the expected 4 incidents are returned + - Ensure executeCommand was called twice + """ + execute_command = mocker.patch.object(demisto, "executeCommand", side_effect=mock_execute_command) + args = { + "incidentTypes": "Phishing,Malware", + "timeField": "created", + "fromDate": "2019-02-01T00:00:00", + "toDate": "3 days ago", + "limit": "10", + "includeContext": "false", + "pageSize": "3", + } + results = get_incidents_by_query(args) + assert len(results) == 4 + assert execute_command.call_count == 2 + + +def test_get_incidents_by_query_with_populate_fields(mocker): + """ + Given: + - A mock incidents database (INCIDENTS_LIST) + - Search incidents query arguments that should return 4 incidents (same as the sanity test) + When: + - populateFields is id,name,testField + Then: + - Ensure the expected 4 incidents are returned + - Ensure the returned incidents' keys are "id", "name", and "testField" only. + """ + mocker.patch.object(demisto, "executeCommand", side_effect=mock_execute_command) + args = { + "incidentTypes": "Phishing,Malware", + "timeField": "created", + "fromDate": "2019-02-01T00:00:00", + "toDate": "3 days ago", + "limit": "10", + "includeContext": "false", + "pageSize": "10", + "populateFields": "id,name,testField" + } + results = get_incidents_by_query(args) + assert len(results) == 4 + assert all(set(inc.keys()) == {"id", "name", "testField"} for inc in results) + + +def test_get_incidents_by_query_with_context(mocker): + """ + - A mock incidents database (INCIDENTS_LIST) + - Search incidents query arguments that should return 4 incidents (same as the sanity test) + When: + - includeContext is true + Then: + - Ensure the expected 4 incidents are returned + - Ensure each incidents has a non-empty context key + """ + mocker.patch.object(demisto, "executeCommand", side_effect=mock_execute_command) + args = { + "incidentTypes": "Phishing,Malware", + "timeField": "created", + "fromDate": "2019-02-01T00:00:00", + "toDate": "3 days ago", + "limit": "10", + "includeContext": "true", + "pageSize": "10", + } + results = get_incidents_by_query(args) + assert len(results) == 4 + assert all(inc["context"] for inc in results) + + +def test_get_incidents_by_query_timefield_is_modified(mocker): + """ + - A mock incidents database (INCIDENTS_LIST) + - Search incidents query arguments + When: + - timeField is modified + Then: + - Ensure the expected 1 incident is returned + """ + execute_command = mocker.patch.object(demisto, "executeCommand", side_effect=mock_execute_command) + args = { + "timeField": "modified", + "fromDate": "2020-01-02T00:00:00Z", + "toDate": "2020-01-03T00:00:00Z", + "limit": "10", + "includeContext": "false", + "pageSize": "3", + } + results = get_incidents_by_query(args) + assert len(results) == 1 + assert execute_command.call_count == 1 diff --git a/Packs/Base/ReleaseNotes/1_33_37.md b/Packs/Base/ReleaseNotes/1_33_37.md new file mode 100644 index 000000000000..cdbd75c00ad1 --- /dev/null +++ b/Packs/Base/ReleaseNotes/1_33_37.md @@ -0,0 +1,18 @@ + +#### Scripts + +##### GetIncidentsByQuery +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. +- Moved the implementation to *GetIncidentsApiModule*. +- The *includeContext* argument is now deprecated due to performance considerations. Rather than using this argument, it is recommended to retrieve the context of the incidents separately, preferably for a limited number of incidents. + + + +##### DBotFindSimilarIncidentsByIndicators +- Updated the Docker image to: *demisto/ml:1.0.0.88591*. +- Internal code enhancements for improved performance. + +##### DBotFindSimilarIncidents +- Updated the Docker image to: *demisto/ml:1.0.0.88591*. +- Internal code enhancements for improved performance. + diff --git a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.py b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.py index c198b2208fb9..c7eded235f00 100644 --- a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.py +++ b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.py @@ -4,6 +4,7 @@ import warnings import numpy as np import re +from copy import deepcopy from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.base import BaseEstimator, TransformerMixin import json @@ -11,6 +12,8 @@ from scipy.spatial.distance import cdist from typing import Any +from GetIncidentsApiModule import * # noqa: E402 + warnings.simplefilter("ignore") warnings.filterwarnings('ignore', category=UserWarning) @@ -29,7 +32,7 @@ MESSAGE_NO_CURRENT_INCIDENT = f"- {INCIDENT_ALIAS.capitalize()} %s does not exist within the given time range. " \ f"Please check incidentId value or that you are running the command within an {INCIDENT_ALIAS}." MESSAGE_NO_FIELD = f"- %s field(s) does not exist in the current {INCIDENT_ALIAS}." -MESSAGE_INCORRECT_FIELD = "- %s field(s) don't/doesn't exist within the fetched {INCIDENT_ALIAS}s." +MESSAGE_INCORRECT_FIELD = f"- %s field(s) don't/doesn't exist within the fetched {INCIDENT_ALIAS}s." SIMILARITY_COLUNM_NAME = f'similarity {INCIDENT_ALIAS}' SIMILARITY_COLUNM_NAME_INDICATOR = 'similarity indicators' @@ -72,15 +75,39 @@ def keep_high_level_field(incidents_field: list[str]) -> list[str]: return [x.split('.')[0] if '.' in x else x for x in incidents_field] -def wrapped_list(obj: list) -> list: - """ - Wrapped object into a list if not list - :param obj: - :return: - """ - if not isinstance(obj, list): - return [obj] - return obj +def extract_values(data: dict | list, path: str, values_to_exclude: list) -> list: + """Recursively extracts values from nested object by path (dot notation). + + For example: extract_values( + data={"A": [ + {"B": 1, "C": 0}, + {"B": 2}, + {"B": None}, + {"B": "N/A"}, + ]}, + path="A.B", + values_to_exclude=[None, "N/A"], + ) == [1, 2] + + Args: + data (dict | list): The object to extract values from. + path (str): The path (dot notation) to the values to extract. + values_to_exclude (list): A list of values to exclude from result. + + Returns: + list: The extracted values. + """ + def recurse(obj: Any, keys: list[str]): + if not keys: + result = obj if isinstance(obj, list) else [obj] + return [val for val in result if val not in values_to_exclude] + if isinstance(obj, dict): + if keys[0] in obj: + return recurse(obj[keys[0]], keys[1:]) + elif isinstance(obj, list): + return [result for item in obj for result in recurse(item, keys)] + return [] + return recurse(data, path.split(".")) def preprocess_incidents_field(incidents_field: str, prefix_to_remove: list[str]) -> str: @@ -190,20 +217,13 @@ def normalize_command_line(command: str) -> str: return '' -def fill_nested_fields(incidents_df: pd.DataFrame, incidents: pd.DataFrame, *list_of_field_list: list[str]) -> \ +def fill_nested_fields(incidents_df: pd.DataFrame, incidents: dict | list, *list_of_field_list: list[str]) -> \ pd.DataFrame: for field_type in list_of_field_list: for field in field_type: if '.' in field: - if isinstance(incidents, list): - value_list = [wrapped_list(demisto.dt(incident, field)) for incident in incidents] - value_list = [' '.join(set(filter(lambda x: x not in ['None', None, 'N/A'], x))) for x in - value_list] - else: - value_list = wrapped_list(demisto.dt(incidents, field)) - value_list = ' '.join( # type: ignore - set(filter(lambda x: x not in ['None', None, 'N/A'], value_list))) # type: ignore - incidents_df[field] = value_list + value_list = extract_values(incidents, field, values_to_exclude=['None', None, 'N/A']) + incidents_df[field] = ' '.join(value_list) return incidents_df @@ -537,20 +557,14 @@ def get_incident_by_id(incident_id: str, populate_fields: list[str], from_date: """ populate_fields_value = ' , '.join(populate_fields) message_of_values = build_message_of_values([incident_id, populate_fields_value, from_date, to_date]) - demisto.debug(f'Executing GetIncidentsByQuery, {message_of_values}') - res = demisto.executeCommand('GetIncidentsByQuery', { - 'query': "id:(%s)" % incident_id, + demisto.debug(f'Calling get_incidents_by_query, {message_of_values}') + incidents = get_incidents_by_query({ + 'query': f"id:({incident_id})", 'populateFields': populate_fields_value, 'fromDate': from_date, 'toDate': to_date, }) - if is_error(res): - return_error(res) - if not json.loads(res[0]['Contents']): - return None - else: - incident = json.loads(res[0]['Contents']) - return incident[0] + return incidents[0] if incidents else None def get_all_incidents_for_time_window_and_exact_match(exact_match_fields: list[str], populate_fields: list[str], @@ -580,17 +594,15 @@ def get_all_incidents_for_time_window_and_exact_match(exact_match_fields: list[s query += " %s" % query_sup populate_fields_value = ' , '.join(populate_fields) - demisto.debug(f'Executing GetIncidentsByQuery, {build_message_of_values([populate_fields_value, from_date, to_date, limit])}') - res = demisto.executeCommand('GetIncidentsByQuery', { + msg_of_values = build_message_of_values([populate_fields_value, from_date, to_date, limit]) + demisto.debug(f'Calling get_incidents_by_query, {msg_of_values}') + incidents = get_incidents_by_query({ 'query': query, 'populateFields': populate_fields_value, 'fromDate': from_date, 'toDate': to_date, 'limit': limit }) - if is_error(res): - return_error(res) - incidents = json.loads(res[0]['Contents']) if len(incidents) == 0: msg += "%s \n" % MESSAGE_NO_INCIDENT_FETCHED return None, msg @@ -954,7 +966,7 @@ def main(): incorrect_fields=incorrect_fields) # Dumps all dict in the current incident - incident_df = dumps_json_field_in_incident(incident) + incident_df = dumps_json_field_in_incident(deepcopy(incident)) incident_df = fill_nested_fields(incident_df, incident, similar_text_field, similar_categorical_field) # Model prediction diff --git a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.yml b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.yml index 64fb0bb89c84..2a114966535d 100644 --- a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.yml +++ b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents.yml @@ -84,7 +84,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/ml:1.0.0.84027 +dockerimage: demisto/ml:1.0.0.88591 runas: DBotWeakRole runonce: true tests: diff --git a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents_test.py b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents_test.py index d4f5c314af98..28cbde4f277b 100644 --- a/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents_test.py +++ b/Packs/Base/Scripts/DBotFindSimilarIncidents/DBotFindSimilarIncidents_test.py @@ -1,8 +1,8 @@ import demistomock as demisto -import json import numpy as np import pandas as pd import pytest +from copy import deepcopy CURRENT_INCIDENT_NOT_EMPTY = [ {'id': '123', 'commandline': 'powershell IP=1.1.1.1', 'CustomFields': {"nested_field": 'value_nested_field'}, @@ -45,11 +45,11 @@ def executeCommand(command, args): global SIMILAR_INDICATORS, FETCHED_INCIDENT, CURRENT_INCIDENT if command == 'DBotFindSimilarIncidentsByIndicators': return [[], {'Contents': SIMILAR_INDICATORS, 'Type': 'note', 'Tags': [TAG_SCRIPT_INDICATORS]}] - if command == 'GetIncidentsByQuery': - if 'limit' in args: - return [{'Contents': json.dumps(FETCHED_INCIDENT), 'Type': 'note'}] - else: - return [{'Contents': json.dumps(CURRENT_INCIDENT), 'Type': 'note'}] + if command == 'getIncidents': + if '-id:' in args.get("query"): # query for similar incidents + return [{'Contents': {"data": FETCHED_INCIDENT}, 'Type': 'note'}] + else: # query for current incident + return [{'Contents': {"data": CURRENT_INCIDENT}, 'Type': 'note'}] return None @@ -102,9 +102,9 @@ def test_euclidian_similarity_capped(): def test_main_regular(mocker): from DBotFindSimilarIncidents import SIMILARITY_COLUNM_NAME_INDICATOR, SIMILARITY_COLUNM_NAME, main, COLUMN_ID, COLUMN_TIME global SIMILAR_INDICATORS, FETCHED_INCIDENT, CURRENT_INCIDENT - FETCHED_INCIDENT = FETCHED_INCIDENT_NOT_EMPTY - CURRENT_INCIDENT = CURRENT_INCIDENT_NOT_EMPTY - SIMILAR_INDICATORS = SIMILAR_INDICATORS_NOT_EMPTY + FETCHED_INCIDENT = deepcopy(FETCHED_INCIDENT_NOT_EMPTY) + CURRENT_INCIDENT = deepcopy(CURRENT_INCIDENT_NOT_EMPTY) + SIMILAR_INDICATORS = deepcopy(SIMILAR_INDICATORS_NOT_EMPTY) mocker.patch.object(demisto, 'args', return_value={ 'incidentId': 12345, @@ -122,7 +122,6 @@ def test_main_regular(mocker): 'aggreagateIncidentsDifferentDate': 'False', 'includeIndicatorsSimilarity': 'True' }) - mocker.patch.object(demisto, 'dt', return_value=None) mocker.patch.object(demisto, 'executeCommand', side_effect=executeCommand) res, _ = main() assert ('empty_current_incident_field' not in res.columns) @@ -142,9 +141,9 @@ def test_main_no_indicators_found(mocker): """ from DBotFindSimilarIncidents import SIMILARITY_COLUNM_NAME_INDICATOR, SIMILARITY_COLUNM_NAME, main, COLUMN_ID, COLUMN_TIME global SIMILAR_INDICATORS, FETCHED_INCIDENT, CURRENT_INCIDENT - FETCHED_INCIDENT = FETCHED_INCIDENT_NOT_EMPTY - CURRENT_INCIDENT = CURRENT_INCIDENT_NOT_EMPTY - SIMILAR_INDICATORS = SIMILAR_INDICATORS_EMPTY + FETCHED_INCIDENT = deepcopy(FETCHED_INCIDENT_NOT_EMPTY) + CURRENT_INCIDENT = deepcopy(CURRENT_INCIDENT_NOT_EMPTY) + SIMILAR_INDICATORS = deepcopy(SIMILAR_INDICATORS_EMPTY) mocker.patch.object(demisto, 'args', return_value={ 'incidentId': 12345, @@ -162,7 +161,6 @@ def test_main_no_indicators_found(mocker): 'aggreagateIncidentsDifferentDate': 'False', 'includeIndicatorsSimilarity': 'True' }) - mocker.patch.object(demisto, 'dt', return_value=None) mocker.patch.object(demisto, 'executeCommand', side_effect=executeCommand) res, _ = main() assert ('empty_current_incident_field' not in res.columns) @@ -180,9 +178,9 @@ def test_main_no_fetched_incidents_found(mocker): """ from DBotFindSimilarIncidents import MESSAGE_NO_INCIDENT_FETCHED, main global SIMILAR_INDICATORS, FETCHED_INCIDENT, CURRENT_INCIDENT - FETCHED_INCIDENT = FETCHED_INCIDENT_EMPTY - CURRENT_INCIDENT = CURRENT_INCIDENT_NOT_EMPTY - SIMILAR_INDICATORS = SIMILAR_INDICATORS_NOT_EMPTY + FETCHED_INCIDENT = deepcopy(FETCHED_INCIDENT_EMPTY) + CURRENT_INCIDENT = deepcopy(CURRENT_INCIDENT_NOT_EMPTY) + SIMILAR_INDICATORS = deepcopy(SIMILAR_INDICATORS_NOT_EMPTY) mocker.patch.object(demisto, 'args', return_value={ 'incidentId': 12345, @@ -200,7 +198,6 @@ def test_main_no_fetched_incidents_found(mocker): 'aggreagateIncidentsDifferentDate': 'False', 'includeIndicatorsSimilarity': 'True' }) - mocker.patch.object(demisto, 'dt', return_value=None) mocker.patch.object(demisto, 'executeCommand', side_effect=executeCommand) res = main() assert (not res[0]) @@ -229,9 +226,9 @@ def test_main_all_incorrect_field(mocker): """ from DBotFindSimilarIncidents import MESSAGE_INCORRECT_FIELD, main global SIMILAR_INDICATORS, FETCHED_INCIDENT, CURRENT_INCIDENT - FETCHED_INCIDENT = FETCHED_INCIDENT_NOT_EMPTY - CURRENT_INCIDENT = CURRENT_INCIDENT_NOT_EMPTY - SIMILAR_INDICATORS = SIMILAR_INDICATORS_NOT_EMPTY + FETCHED_INCIDENT = deepcopy(FETCHED_INCIDENT_NOT_EMPTY) + CURRENT_INCIDENT = deepcopy(CURRENT_INCIDENT_NOT_EMPTY) + SIMILAR_INDICATORS = deepcopy(SIMILAR_INDICATORS_NOT_EMPTY) wrong_field_1 = 'wrong_field_1' wrong_field_2 = 'wrong_field_2' wrong_field_3 = 'wrong_field_3' @@ -252,7 +249,6 @@ def test_main_all_incorrect_field(mocker): 'aggreagateIncidentsDifferentDate': 'False', 'includeIndicatorsSimilarity': 'True' }) - mocker.patch.object(demisto, 'dt', return_value=None) mocker.patch.object(demisto, 'executeCommand', side_effect=executeCommand) df, msg = main() assert (not df) @@ -268,9 +264,9 @@ def test_main_incident_truncated(mocker): """ from DBotFindSimilarIncidents import main, MESSAGE_WARNING_TRUNCATED global SIMILAR_INDICATORS, FETCHED_INCIDENT, CURRENT_INCIDENT - FETCHED_INCIDENT = FETCHED_INCIDENT_NOT_EMPTY - CURRENT_INCIDENT = CURRENT_INCIDENT_NOT_EMPTY - SIMILAR_INDICATORS = SIMILAR_INDICATORS_NOT_EMPTY + FETCHED_INCIDENT = deepcopy(FETCHED_INCIDENT_NOT_EMPTY) + CURRENT_INCIDENT = deepcopy(CURRENT_INCIDENT_NOT_EMPTY) + SIMILAR_INDICATORS = deepcopy(SIMILAR_INDICATORS_NOT_EMPTY) correct_field_1 = 'commandline' wrong_field_2 = 'wrong_field_2' wrong_field_3 = 'wrong_field_3' @@ -291,7 +287,6 @@ def test_main_incident_truncated(mocker): 'aggreagateIncidentsDifferentDate': 'False', 'includeIndicatorsSimilarity': 'True' }) - mocker.patch.object(demisto, 'dt', return_value=None) mocker.patch.object(demisto, 'executeCommand', side_effect=executeCommand) df, msg = main() limit = demisto.args()['limit'] @@ -301,29 +296,27 @@ def test_main_incident_truncated(mocker): def test_main_incident_nested(mocker): """ - Test if fetched incident truncated - Should return MESSAGE_WARNING_TRUNCATED in the message - :param mocker: - :return: + Given: Same test case as in test_main_regular but with a nested field as a similarTextField + When: Running main() + Then: Ensure the nested field exists in the results """ from DBotFindSimilarIncidents import main global SIMILAR_INDICATORS, FETCHED_INCIDENT, CURRENT_INCIDENT - FETCHED_INCIDENT = FETCHED_INCIDENT_NOT_EMPTY - CURRENT_INCIDENT = CURRENT_INCIDENT_NOT_EMPTY - SIMILAR_INDICATORS = SIMILAR_INDICATORS_NOT_EMPTY - wrong_field_2 = 'wrong_field_2' - wrong_field_3 = 'wrong_field_3' - wrong_field_4 = 'wrong_field_4' - nested_field = 'xdralerts.cmd' + FETCHED_INCIDENT = deepcopy(FETCHED_INCIDENT_NOT_EMPTY) + CURRENT_INCIDENT = deepcopy(CURRENT_INCIDENT_NOT_EMPTY) + SIMILAR_INDICATORS = deepcopy(SIMILAR_INDICATORS_NOT_EMPTY) + nested_field = 'CustomFields.nested_field' mocker.patch.object(demisto, 'args', return_value={ 'incidentId': 12345, - 'similarTextField': nested_field, - 'similarCategoricalField': wrong_field_2, - 'similarJsonField': wrong_field_3, - 'limit': 3, + 'similarTextField': f'{nested_field},incident.commandline, commandline, command, ' + 'empty_current_incident_field, empty_fetched_incident_field', + 'similarCategoricalField': 'signature, filehash, incident.commandline', + 'similarJsonField': '', + 'limit': 10000, 'fieldExactMatch': '', - 'fieldsToDisplay': wrong_field_4, + 'fieldsToDisplay': 'filehash, destinationip, closeNotes, sourceip, alertdescription', 'showIncidentSimilarityForAllFields': True, 'minimunIncidentSimilarity': 0.2, 'maxIncidentsToDisplay': 100, @@ -331,11 +324,10 @@ def test_main_incident_nested(mocker): 'aggreagateIncidentsDifferentDate': 'False', 'includeIndicatorsSimilarity': 'True' }) - mocker.patch.object(demisto, 'dt', return_value=['nested_val_1', 'nested_val_2']) mocker.patch.object(demisto, 'executeCommand', side_effect=executeCommand) df, _ = main() assert not df.empty - assert (df['similarity %s' % nested_field] == [1.0, 1.0, 1.0]).all() + assert (df[f"similarity {nested_field}"] > 0).all() def test_get_get_data_from_indicators_automation(): diff --git a/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators.py b/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators.py index 3777f15814cb..a179962d42aa 100644 --- a/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators.py +++ b/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators.py @@ -9,6 +9,8 @@ import re import math +from GetIncidentsApiModule import * # noqa: E402 + SEARCH_INDICATORS_LIMIT = 10000 SEARCH_INDICATORS_PAGE_SIZE = 500 @@ -236,8 +238,8 @@ def get_related_incidents( "fromDate": from_date, } demisto.debug(f"Executing GetIncidentsByQuery with {args=}") - res = execute_command("GetIncidentsByQuery", args, fail_on_error=True) - incident_ids = [incident[INCIDENT_ID_FIELD] for incident in json.loads(res)] + incidents = get_incidents_by_query(args) + incident_ids = [incident[INCIDENT_ID_FIELD] for incident in incidents] demisto.debug(f"Found {len(incident_ids)} related incidents: {incident_ids}") return incident_ids @@ -364,8 +366,8 @@ def enrich_incidents( "populateFields": ",".join(fields_to_display), } demisto.debug(f"Executing GetIncidentsByQuery with {args=}") - res = execute_command("GetIncidentsByQuery", args, fail_on_error=True) - incidents_map: dict[str, dict] = {incident[INCIDENT_ID_FIELD]: incident for incident in json.loads(res)} + res = get_incidents_by_query(args) + incidents_map: dict[str, dict] = {incident[INCIDENT_ID_FIELD]: incident for incident in res} if CREATED_FIELD in fields_to_display: incidents[CREATED_FIELD] = [ dateparser.parse(incidents_map[inc_id][CREATED_FIELD]).strftime(DATE_FORMAT) # type: ignore diff --git a/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators.yml b/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators.yml index 4fae308f3e32..a13bce442cf4 100644 --- a/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators.yml +++ b/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators.yml @@ -42,7 +42,7 @@ script: '-' subtype: python3 timeout: '0' type: python -dockerimage: demisto/ml:1.0.0.86706 +dockerimage: demisto/ml:1.0.0.88591 runas: DBotWeakRole tests: - DBotFindSimilarIncidentsByIndicators - Test diff --git a/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators_test.py b/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators_test.py index b4fb0457697f..45ebbb4a9a38 100644 --- a/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators_test.py +++ b/Packs/Base/Scripts/DBotFindSimilarIncidentsByIndicators/DBotFindSimilarIncidentsByIndicators_test.py @@ -1,4 +1,3 @@ -import json import numpy as np import pandas as pd import pytest @@ -35,16 +34,17 @@ def get_related_indicators(incident_id: str): def mock_execute_command(command: str, args: dict): - query: str = args.get("query") or "" - from_date: str = args.get("fromDate") or "" match command: - case "GetIncidentsByQuery": - match = re.search(r"incident\.id:\((.*)\)", query) + case "getIncidents": + query: str = args.get("query") or "" + from_date: str = args.get("fromdate") or "" + match = re.search(r"incident\.id:\(([^\)]*)\)", query) incident_ids = set(match.group(1).split(" ") if match and match.group(1) else []) - res = json.dumps([ + res = {"data": [ {k: v for k, v in i.items() if k in args["populateFields"] or k == "id"} for i in INCIDENTS_LIST - if i["id"] in incident_ids and (not from_date or parse(i["created"]) >= parse(from_date)) - ]) + if i["id"] in incident_ids + and (not from_date or parse(i["created"]) >= parse(from_date).replace(tzinfo=None)) + ]} case _: raise Exception(f"Unmocked command: {command}") return [{"Contents": res, "Type": "json"}] diff --git a/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery.py b/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery.py index 5edc4ee984f5..f290e6d84708 100644 --- a/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery.py +++ b/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery.py @@ -2,244 +2,43 @@ import pickle import uuid -from dateutil import parser -PREFIXES_TO_REMOVE = ['incident.'] -PAGE_SIZE = int(demisto.args().get('pageSize', 100)) -PYTHON_MAGIC = "$$##" - - -def parse_datetime(datetime_str): - try: - return parser.parse(datetime_str).isoformat() - except Exception: - return datetime_str - - -def parse_relative_time(datetime_str): - if datetime_str: - datetime_str = datetime_str.lower() - try: - res = re.search("([0-9]+) (minute|minutes|hour|hours|day|days|week|weeks|month|months|year|years) ago", - datetime_str) - if res: - number = int(res.group(1)) - unit = res.group(2) - if unit in ['minute', 'hour', 'day', 'week', 'month', 'year']: - unit += "s" - if unit == 'years': - unit = 'days' - number *= 365 - elif unit == 'months': - number *= 43800 - unit = 'minutes' - - kargs = {} - kargs[unit] = int(number) - result = datetime.now() - timedelta(**kargs) - return result - except Exception: - return None - - -def get_context(incident_id): - res = demisto.executeCommand("getContext", {'id': incident_id}) - try: - return res[0]['Contents'].get('context') or {} - except Exception: - return {} - - -def build_incidents_query(extra_query, incident_types, time_field, from_date, to_date, non_empty_fields): - query_parts = [] - if extra_query: - query_parts.append(extra_query) - if incident_types: - types = ['"{}"'.format(x.strip()) if '*' not in x else '{}'.format(x.strip()) - for x in incident_types.split(",")] - types_part = "type:({})".format(' '.join(types)) - query_parts.append(types_part) - if from_date: - from_part = '%s:>="%s"' % (time_field, parse_datetime(from_date)) - query_parts.append(from_part) - if to_date: - to_part = '%s:<"%s"' % (time_field, parse_datetime(to_date)) - query_parts.append(to_part) - if len(non_empty_fields) > 0: - non_empty_fields_part = " and ".join("{}:*".format(x) for x in non_empty_fields) - query_parts.append(non_empty_fields_part) - if len(query_parts) == 0: - raise Exception("Incidents query is empty - please fill one of the arguments") - query = " and ".join('({})'.format(x) for x in query_parts) - return query - - -def handle_incident(inc, fields_to_populate, include_context): - # we flat the custom field to the incident structure, like in the context - custom_fields = inc.get('CustomFields', {}) or {} - inc.update(custom_fields) - if fields_to_populate and len(fields_to_populate) > 0: - inc = {k: v for k, v in inc.items() if k.lower() in {val.lower() for val in fields_to_populate}} - if include_context: - inc['context'] = get_context(inc['id']) - return inc - - -def is_incident_contains_python_magic(inc): - return PYTHON_MAGIC in json.dumps(inc) - - -def get_fields_to_populate_arg(fields_to_populate): - incidents_fields_to_populate = [] - for field in fields_to_populate: - if "." in field: - # handle complex field case - incidents_fields_to_populate.append(field[:field.find(".")]) - else: - incidents_fields_to_populate.append(field) - return ",".join(incidents_fields_to_populate) - - -def get_incidents_by_page(args, page, fields_to_populate, include_context): - args['page'] = page - if is_demisto_version_ge('6.2.0') and len(fields_to_populate) > 0: - args['populateFields'] = get_fields_to_populate_arg(fields_to_populate) - res = demisto.executeCommand("getIncidents", args) - if is_error(res): - error_message = get_error(res) - raise Exception("Failed to get incidents by query args: %s error: %s" % (args, error_message)) - if res[0]['Contents'].get('data') is None: - return [] - incidents = res[0]['Contents'].get('data') or [] - - parsed_incidents = [] - for inc in incidents: - new_incident = handle_incident(inc, fields_to_populate, include_context) - if is_incident_contains_python_magic(new_incident): - demisto.debug("Warning: skip incident [id:%s] that contains python magic" % str(inc['id'])) - continue - parsed_incidents.append(new_incident) - return parsed_incidents - - -def get_demisto_datetme_format(date_string): - if date_string: - date_object = None - # try to parse date string - try: - date_object = parser.parse(date_string) - except Exception: - pass - # try to parse relative time - if date_object is None and date_string.strip().endswith("ago"): - date_object = parse_relative_time(date_string) - - if date_object: - return date_object.astimezone().isoformat('T') - else: - return None - - -def get_incidents(query, time_field, size, from_date, to_date, fields_to_populate, include_context): - query_size = min(PAGE_SIZE, size) - args = {"query": query, "size": query_size, "sort": "%s.%s" % (time_field, "desc")} - # apply only when created time field - if time_field == 'created': - if from_date: - from_datetime = get_demisto_datetme_format(from_date) - if from_datetime: - args['fromdate'] = from_datetime - else: - demisto.results("did not set from date due to a wrong format: " + from_date) - - if to_date: - to_datetime = get_demisto_datetme_format(to_date) - if to_datetime: - args['todate'] = to_datetime - else: - demisto.results("did not set to date due to a wrong format: " + from_date) - - incident_list = [] # type: ignore - page = 0 - while len(incident_list) < size: - incidents = get_incidents_by_page(args, page, fields_to_populate, include_context) - if not incidents: - break - incident_list += incidents - page += 1 - return incident_list[:size] - - -def get_comma_sep_list(value): - value = value.replace('|', ',') - return map(lambda x: x.strip(), value.split(",")) - - -def preprocess_incidents_fields_list(incidents_fields): - res = [] - for field in incidents_fields: - field = field.strip() - for prefix in PREFIXES_TO_REMOVE: - if field.startswith(prefix): - field = field[len(prefix):] - res.append(field) - return res +from GetIncidentsApiModule import * + + +def encode_outputs(incidents: list[dict], output_format: str) -> str | bytes: + match output_format: + case "pickle": + return pickle.dumps(incidents, protocol=2) # guardrails-disable-line + case "json": + return json.dumps(incidents) + case _: + raise DemistoException(f"Invalid output format: {output_format}") + + +def to_file_entry(incidents: list[dict], output_format: str) -> dict[str, Any]: + file_name = str(uuid.uuid4()) + encoded_data = encode_outputs(incidents, output_format) + return fileResult(file_name, encoded_data) | { + "Contents": incidents, + "HumanReadable": f"Fetched {len(incidents)} incidents successfully", + "EntryContext": { + "GetIncidentsByQuery": { + "Filename": file_name, + "FileFormat": output_format, + }, + } + } def main(): try: - # fetch query - d_args = dict(demisto.args()) - for arg_name in ['NonEmptyFields', 'populateFields']: - split_argument_list = get_comma_sep_list(d_args.get(arg_name, '')) - split_argument_list = [x for x in split_argument_list if len(x) > 0] - if 'openDuration' in split_argument_list: # pragma: no cover - split_argument_list.append('openduration') # pragma: no cover - split_argument_list.remove('openDuration') # pragma: no cover - d_args[arg_name] = preprocess_incidents_fields_list(split_argument_list) - query = build_incidents_query(d_args.get('query'), - d_args.get('incidentTypes'), - d_args['timeField'], - d_args.get('fromDate'), - d_args.get('toDate'), - d_args.get('NonEmptyFields')) - fields_to_populate = d_args.get('populateFields') # type: ignore - if len(fields_to_populate) > 0: # type: ignore - fields_to_populate += d_args['NonEmptyFields'] - fields_to_populate.append('id') - fields_to_populate = set([x for x in fields_to_populate if x]) # type: ignore - include_context = d_args['includeContext'] == 'true' - incidents = get_incidents(query, d_args['timeField'], - int(d_args['limit']), - d_args.get('fromDate'), - d_args.get('toDate'), - fields_to_populate, - include_context) - - # output - file_name = str(uuid.uuid4()) - output_format = d_args['outputFormat'] - if output_format == 'pickle': - data_encoded = pickle.dumps(incidents, protocol=2) - elif output_format == 'json': - data_encoded = json.dumps(incidents) # type: ignore - else: - raise Exception("Invalid output format: %s" % output_format) - - entry = fileResult(file_name, data_encoded) - entry['Contents'] = incidents - entry['HumanReadable'] = "Fetched %d incidents successfully by the query: %s" % (len(incidents), query) - entry['EntryContext'] = { - 'GetIncidentsByQuery': { - 'Filename': file_name, - 'FileFormat': output_format, - } - } - return entry + args = demisto.args() + incidents = get_incidents_by_query(args) + return_results(to_file_entry(incidents, args["outputFormat"])) except Exception as e: return_error(str(e)) -if __name__ in ['builtins', '__main__']: - entry = main() - demisto.results(entry) +if __name__ in ["builtins", "__main__"]: + main() diff --git a/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery.yml b/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery.yml index d1a0cfa3e75d..609d11ea0fe2 100644 --- a/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery.yml +++ b/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery.yml @@ -12,7 +12,8 @@ args: name: limit - auto: PREDEFINED defaultValue: 'false' - description: Whether to query and fetch incident context. Can be "true" or "false". The default is "false". + deprecated: true + description: Deprecated due to performance considerations. Rather than using this argument, it is recommended to retrieve the context of the incidents separately, preferably for a limited number of incidents. name: includeContext predefined: - 'true' @@ -36,7 +37,7 @@ args: - description: A comma-separated list of fields in the object to poplulate. name: populateFields - defaultValue: '100' - description: Incidents query batch size + description: Incidents query batch size. name: pageSize comment: |- Gets a list of incident objects and the associated incident outputs that @@ -62,7 +63,7 @@ tags: - ml timeout: 60µs type: python -dockerimage: demisto/python3:3.10.12.66339 +dockerimage: demisto/python3:3.10.13.87159 tests: - Create Phishing Classifier V2 ML Test fromversion: 5.0.0 diff --git a/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery_test.py b/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery_test.py index 0017c037b7cb..182710e062ce 100644 --- a/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery_test.py +++ b/Packs/Base/Scripts/GetIncidentsByQuery/GetIncidentsByQuery_test.py @@ -1,191 +1,64 @@ -from GetIncidentsByQuery import build_incidents_query, get_incidents, parse_relative_time, main, \ - preprocess_incidents_fields_list, get_demisto_datetme_format, get_fields_to_populate_arg, PYTHON_MAGIC, \ - get_comma_sep_list - -from CommonServerPython import * - -incident1 = { - 'id': 1, - 'name': 'This is incident1', - 'type': 'Phishing', - 'severity': 0, - 'status': 1, - 'created': '2019-01-02', - 'CustomFields': { - 'testField': "testValue" - }, - 'closed': '0001-01-01T00:00:00Z', - 'labels': [{'type': 'subject', 'value': 'This subject1'}, {'type': 'unique', 'value': 'This subject1'}], - 'attachment': [{'name': 'Test word1 word2'}] -} -incident2 = dict(incident1) -incident2['id'] = 2 - -incident_with_magic = dict(incident1) -incident_with_magic['id'] = 3 -incident_with_magic['name'] = PYTHON_MAGIC - - -def get_args(): - args = {} - args['incidentTypes'] = 'Phishing,Malware' - args['timeField'] = 'created' - args['fromDate'] = '2019-10-01' - args['toDate'] = '3 days ago' - args['limit'] = '10' - args['includeContext'] = 'false' - args['outputFormat'] = 'json' - args['pageSize'] = '10' - return args - - -def test_build_query(mocker): - mocker.patch.object(demisto, 'args', side_effect=get_args) - query = build_incidents_query("Extra part", "Phishing,Malware", "modified", "2019-01-10", "3 days ago", - ["status", "closeReason"]) - assert query == '(Extra part) and (type:("Phishing" "Malware")) and (modified:>="2019-01-10T00:00:00") ' \ - 'and (modified:<"3 days ago") and (status:* and closeReason:*)' - query = build_incidents_query("Extra part", "Phishing", "modified", "2019-01-10", "3 days ago", - ["status"]) - assert query == '(Extra part) and (type:("Phishing")) and (modified:>="2019-01-10T00:00:00") ' \ - 'and (modified:<"3 days ago") and (status:*)' - - -def test_get_incidents(mocker): - mocker.patch.object(demisto, 'args', side_effect=get_args) - size = 100 - query = 'query' - - def validate_args(command, args): - assert args.get('fromdate') - assert len(args.get('fromdate')) > 5 - assert args.get('todate') - assert len(args.get('todate')) > 5 - assert args['size'] == size - assert args['query'] == query - return [{'Type': entryTypes['note'], 'Contents': {'data': []}}] - - mocker.patch.object(demisto, 'executeCommand', side_effect=validate_args) - get_incidents(query, "created", size, "3 days ago", "1 days ago", None, False) - get_incidents(query, "created", size, "3 months ago", "1 month ago", None, False) - get_incidents(query, "created", size, "3 weeks ago", "1 weeks ago", None, False) - get_incidents(query, "created", size, "2020-02-16T17:45:53.179489", "2020-02-20", None, False) - - def validate_args_without_from(command, args): - assert args.get('fromdate') is None - return [{'Type': entryTypes['note'], 'Contents': {'data': []}}] - - mocker.patch.object(demisto, 'executeCommand', side_effect=validate_args_without_from) - - get_incidents(query, "created", size, None, None, None, False) - get_incidents(query, "created", size, "3 min ago", None, None, False) - - -def test_parse_relative_time(): - threshold = 2 - t1 = parse_relative_time("3 days ago") - t2 = datetime.now() - timedelta(days=3) - assert abs((t2 - t1)).total_seconds() < threshold - - t1 = parse_relative_time("3 minutes ago") - t2 = datetime.now() - timedelta(minutes=3) - assert abs((t2 - t1)).total_seconds() < threshold - - t1 = parse_relative_time("1 months ago") - t2 = datetime.now() - timedelta(minutes=43800) - assert abs((t2 - t1)).total_seconds() < threshold - - t1 = parse_relative_time("1 month ago") - t2 = datetime.now() - timedelta(minutes=43800) - assert abs((t2 - t1)).total_seconds() < threshold - - t1 = parse_relative_time("2 weeks ago") - t2 = datetime.now() - timedelta(weeks=2) - assert abs((t2 - t1)).total_seconds() < threshold - - t1 = parse_relative_time("2 week ago") - t2 = datetime.now() - timedelta(weeks=2) - assert abs((t2 - t1)).total_seconds() < threshold - - t1 = parse_relative_time("2 years ago") - t2 = datetime.now() - timedelta(days=365 * 2) - assert abs((t2 - t1)).total_seconds() < threshold - - -GET_INCIDENTS_COUNTER = 0 - - -def execute_command_get_incidents(command, args): - global GET_INCIDENTS_COUNTER - if GET_INCIDENTS_COUNTER % 2 == 0: - res = [{'Type': entryTypes['note'], 'Contents': {'data': [incident1, incident2]}}] - else: - res = [{'Type': entryTypes['note'], 'Contents': {'data': None}}] - GET_INCIDENTS_COUNTER += 1 - return res - - -def execute_command_get_incidents_with_magic(command, args): - global GET_INCIDENTS_COUNTER - if GET_INCIDENTS_COUNTER % 2 == 0: - res = [{'Type': entryTypes['note'], 'Contents': {'data': [incident1, incident_with_magic]}}] - else: - res = [{'Type': entryTypes['note'], 'Contents': {'data': None}}] - GET_INCIDENTS_COUNTER += 1 - return res - - -def test_main(mocker): - args = dict(get_args()) - mocker.patch.object(demisto, 'args', return_value=args) - mocker.patch.object(demisto, 'executeCommand', side_effect=execute_command_get_incidents) - - entry = main() - assert "Fetched 2 incidents successfully" in entry['HumanReadable'] - assert 'GetIncidentsByQuery' in entry['EntryContext'] - assert 'status' in entry['Contents'][0] - assert 'context' not in entry['Contents'][0] - assert 'testValue' == entry['Contents'][0]['testField'] - - args['includeContext'] = 'true' - entry = main() - assert {} == entry['Contents'][0]['context'] - - args['populateFields'] = 'testField,status' - args['NonEmptyFields'] = 'severity' - entry = main() - assert set(entry['Contents'][0].keys()) == set(['testField', 'status', 'severity', 'id', 'context']) - args.pop('fromDate') - entry = main() - assert set(entry['Contents'][0].keys()) == set(['testField', 'status', 'severity', 'id', 'context']) - - -def test_skip_python_magic(mocker): - args = dict(get_args()) - mocker.patch.object(demisto, 'args', return_value=args) - mocker.patch.object(demisto, 'executeCommand', side_effect=execute_command_get_incidents_with_magic) - - entry = main() - assert entry['Contents'][0]['id'] == 1 - assert len(entry['Contents']) == 1 - - -def test_preprocess_incidents_fields_list(): - incidents_fields = ['incident.emailbody', ' incident.emailsbuject'] - assert preprocess_incidents_fields_list(incidents_fields) == ['emailbody', 'emailsbuject'] - - -def test_get_demisto_datetme_format(): - assert "2020-01-01T00:00:00+00:00" == get_demisto_datetme_format("2020-01-01 00:00:00+00:00") - - -def test_get_fields_to_populate_arg(): - assert get_fields_to_populate_arg(["field1", "grid_field.test1"]) == "field1,grid_field" - assert get_fields_to_populate_arg(["field1", "field2"]) == "field1,field2" - assert get_fields_to_populate_arg([]) == "" - - -def test_get_comma_sep_list(): - split_argument_list = get_comma_sep_list("t1,t2,t3") - split_argument_list = [x for x in split_argument_list if len(x) > 0] - assert split_argument_list == ["t1", "t2", "t3"] +import pytest +from CommonServerPython import DemistoException, EntryType +import demistomock as demisto +import GetIncidentsByQuery + +import json +import pickle + + +def test_encode_outputs(): + """ + Given: Search incidents results + When: Running encode_outputs(): + - once with "json" format + - once with "pickle" format + - once with unexpected format + Then: Ensure the results are encoded correctly, or an error is raised in case of unexpected format + """ + from GetIncidentsByQuery import encode_outputs + incidents = [{"id": 1}] + assert json.loads(encode_outputs(incidents, "json")) == incidents + assert pickle.loads(encode_outputs(incidents, "pickle")) == incidents # guardrails-disable-line + with pytest.raises(DemistoException): + encode_outputs(incidents, "oyvey") + + +def test_to_file_entry(mocker): + """ + Given: Search incidents results + When: Running to_file_entry() with "json" format + Then: Ensure a file entry is returned in the expected format + """ + incidents = [{"id": 1}] + mocker.patch.object(demisto, "investigation", return_value={"id": "inv"}) + res = GetIncidentsByQuery.to_file_entry(incidents, "json") + assert res["Type"] == EntryType.FILE + assert res["EntryContext"]["GetIncidentsByQuery"]["FileFormat"] == "json" + assert res["Contents"] == incidents + + +def test_get_incidents_by_query_sanity_test(mocker): + """ + Given: Search incidents query arguments + When: Running main() + Then: Ensure the expected incident is returned + """ + mocker.patch.object(demisto, "args", return_value={"query": "oyvey", "outputFormat": "json"}) + mocker.patch.object(demisto, "executeCommand", return_value=[{"Contents": {"data": [{"id": 1}]}, "Type": "json"}]) + demisto_results = mocker.patch.object(demisto, "results") + GetIncidentsByQuery.main() + incidents = demisto_results.call_args[0][0]["Contents"] + assert len(incidents) == 1 + assert incidents[0]["id"] == 1 + + +def test_get_incidents_by_query_bad_inputs(mocker): + """ + Given: Search incidents with no query arguments + When: Running main() + Then: Ensure an error entry is returned + """ + return_error = mocker.patch.object(GetIncidentsByQuery, "return_error") + GetIncidentsByQuery.main() + assert "Incidents query is empty" in return_error.call_args[0][0] diff --git a/Packs/Base/Scripts/GetIncidentsByQuery/README.md b/Packs/Base/Scripts/GetIncidentsByQuery/README.md index 6f0a3a521d78..5a98c38e52aa 100644 --- a/Packs/Base/Scripts/GetIncidentsByQuery/README.md +++ b/Packs/Base/Scripts/GetIncidentsByQuery/README.md @@ -28,7 +28,7 @@ This script is used in the following playbooks and scripts. | fromDate | The start date by which to filter incidents. Date format will be the same as in the incidents query page, for example: "3 days ago", ""2019-01-01T00:00:00 \+0200"\). | | toDate | The end date by which to filter incidents. Date format will be the same as in the incidents query page, for example: "3 days ago", ""2019-01-01T00:00:00 \+0200"\). | | limit | The maximum number of incidents to fetch. | -| includeContext | Whether to query and fetch incident context. Can be "true" or "false". The default is "false". | +| includeContext | Deprecated due to performance considerations. Rather than using this argument, it is recommended to retrieve the context of the incidents separately, preferably for a limited number of incidents. | | timeField | The incident field to specify for the date range. Can be "created" or "modified". The default is "created". Due to performance considerations, you should only use "modified" if you have a large number of incidents. | | NonEmptyFields | A comma-separated list of non-empty value incident field names by which to filter incidents. | | outputFormat | The output file format. | diff --git a/Packs/Base/pack_metadata.json b/Packs/Base/pack_metadata.json index 51148d68c8ae..41773a554726 100644 --- a/Packs/Base/pack_metadata.json +++ b/Packs/Base/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Base", "description": "The base pack for Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.33.36", + "currentVersion": "1.33.37", "author": "Cortex XSOAR", "serverMinVersion": "6.0.0", "url": "https://www.paloaltonetworks.com/cortex", From a0f14ec4e512e0f35b8ce48633c69484e5e8656b Mon Sep 17 00:00:00 2001 From: merit-maita <49760643+merit-maita@users.noreply.github.com> Date: Sun, 3 Mar 2024 12:29:39 +0200 Subject: [PATCH 120/272] Stix creator bug (#32950) * added exceptions to be handled * added logs * added log * added logs and removed extra "or" in query * removed debugging lines * added rn * Bump pack from version CommonScripts to 1.13.41. * Bump pack from version CommonScripts to 1.14.1. * Bump pack from version CommonScripts to 1.14.2. * Bump pack from version CommonScripts to 1.14.3. * updated do * edit * Bump pack from version CommonScripts to 1.14.4. --------- Co-authored-by: Content Bot --- Packs/CommonScripts/ReleaseNotes/1_14_4.md | 7 +++++++ .../Scripts/StixCreator/StixCreator.py | 13 ++++++++----- .../Scripts/StixCreator/StixCreator.yml | 2 +- Packs/CommonScripts/pack_metadata.json | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 Packs/CommonScripts/ReleaseNotes/1_14_4.md diff --git a/Packs/CommonScripts/ReleaseNotes/1_14_4.md b/Packs/CommonScripts/ReleaseNotes/1_14_4.md new file mode 100644 index 000000000000..2ab29af0efd0 --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_14_4.md @@ -0,0 +1,7 @@ + +#### Scripts + +##### StixCreator + +- Fixed an issue where *Export Stix* failed when exporting a not STIX compatible object of type `Report`. +- Updated the Docker image to *demisto/py3-tools:1.0.0.88283*. diff --git a/Packs/CommonScripts/Scripts/StixCreator/StixCreator.py b/Packs/CommonScripts/Scripts/StixCreator/StixCreator.py index 012e1e2039c5..05706d5bf1a5 100644 --- a/Packs/CommonScripts/Scripts/StixCreator/StixCreator.py +++ b/Packs/CommonScripts/Scripts/StixCreator/StixCreator.py @@ -9,7 +9,7 @@ from stix2 import Bundle, ExternalReference, Indicator, Vulnerability from stix2 import AttackPattern, Campaign, Malware, Infrastructure, IntrusionSet, Report, ThreatActor from stix2 import Tool, CourseOfAction -from stix2.exceptions import InvalidValueError +from stix2.exceptions import InvalidValueError, MissingPropertiesError from typing import Any from collections.abc import Callable @@ -85,9 +85,9 @@ } -def search_related_indicators(value: str) -> list[dict]: +def search_related_indicators(value: str) -> list[dict]: # pragma: no cover relationships = demisto.searchRelationships({"entities": [value]}).get("data", []) - + demisto.debug(f"found {len(relationships)} relationships") query = "" for rel in relationships: entity_a = rel.get("entityA", "").lower() @@ -103,7 +103,10 @@ def search_related_indicators(value: str) -> list[dict]: if not query: demisto.info(f"No relevant relationship found for indicator: {value}") return [] + query = query[:-4] + demisto.debug(f"using query: {query}") demisto_indicators = demisto.searchIndicators(query=query).get("iocs", []) + demisto.debug(f"found {len(demisto_indicators)} related indicators") return demisto_indicators @@ -370,13 +373,13 @@ def main(): demisto.info(f"Export failure exception: {traceback.format_exc()}") continue - except InvalidValueError: + except (InvalidValueError, MissingPropertiesError): demisto.info( f"Indicator type: {demisto_indicator_type}, with the value: {value} is not STIX compatible. Skipping.") demisto.info(f"Export failure exception: {traceback.format_exc()}") continue - except InvalidValueError: + except (InvalidValueError, MissingPropertiesError): demisto.info( f"Indicator type: {demisto_indicator_type}, with the value: {value} is not STIX compatible. Skipping.") demisto.info(f"Export failure exception: {traceback.format_exc()}") diff --git a/Packs/CommonScripts/Scripts/StixCreator/StixCreator.yml b/Packs/CommonScripts/Scripts/StixCreator/StixCreator.yml index 6ba4e15e5b7a..4f93207e2ee0 100644 --- a/Packs/CommonScripts/Scripts/StixCreator/StixCreator.yml +++ b/Packs/CommonScripts/Scripts/StixCreator/StixCreator.yml @@ -38,7 +38,7 @@ outputs: description: The date/time that the indicator was last seen. type: date scripttarget: 0 -dockerimage: demisto/py3-tools:1.0.0.74403 +dockerimage: demisto/py3-tools:1.0.0.88283 subtype: python3 runas: DBotWeakRole tests: diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index 129c3f1a3cc2..a59bd55690e1 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.14.3", + "currentVersion": "1.14.4", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From fc92a7deb9c7ec024ec51fe36eb8aa4f5604c464 Mon Sep 17 00:00:00 2001 From: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> Date: Sun, 3 Mar 2024 12:37:39 +0200 Subject: [PATCH 121/272] Fix formatting in Readme files (#33125) * Fix formatting * Update README.md --- Packs/Okta/Integrations/Okta_IAM/README.md | 16 ++++++++-------- Packs/Okta/Integrations/Okta_v2/README.md | 18 +++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Packs/Okta/Integrations/Okta_IAM/README.md b/Packs/Okta/Integrations/Okta_IAM/README.md index 4200bc5ae532..8ab7a6503260 100644 --- a/Packs/Okta/Integrations/Okta_IAM/README.md +++ b/Packs/Okta/Integrations/Okta_IAM/README.md @@ -84,7 +84,7 @@ Creates a user. ```!iam-create-user user-profile={\"email\":\"testdemisto2@paloaltonetworks.com\", \"surname\":\"Test\",\"givenname\":\"Demisto\"}``` #### Human Readable Output -### Create User Results (Okta IAM) +##### Create User Results (Okta IAM) |brand|instanceName|success|active|id|username|email|details| |---|---|---|---|---|---|---|---| | Okta IAM | Okta IAM_instance_1 | true | true | 00uujxnbh3uJw4tWA0h7 | testdemisto2@paloaltonetworks.com | testdemisto2@paloaltonetworks.com | id: 00uujxnbh3uJw4tWA0h7
    status: PROVISIONED
    created: 2020-10-18T17:54:30.000Z
    activated: 2020-10-18T17:54:30.000Z
    statusChanged: 2020-10-18T17:54:30.000Z
    lastLogin: null
    lastUpdated: 2020-10-18T17:54:30.000Z
    passwordChanged: null
    type: {"id": "oty8zfz6plq7b0r830h7"}
    profile: {"firstName": "Demisto", "lastName": "Test", "mobilePhone": null, "secondEmail": null, "login": "testdemisto2@paloaltonetworks.com", "email": "testdemisto44@paloaltonetworks.com"}
    credentials: {"provider": {"type": "OKTA", "name": "OKTA"}}
    _links: {"suspend": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/suspend", "method": "POST"}, "schema": {"href": "https://panw-test.oktapreview.com/api/v1/meta/schemas/user/osc8zfz6plq7b0r830h7"}, "resetPassword": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reset_password", "method": "POST"}, "reactivate": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reactivate", "method": "POST"}, "self": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7"}, "type": {"href": "https://panw-test.oktapreview.com/api/v1/meta/types/user/oty8zfz6plq7b0r830h7"}, "deactivate": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/deactivate", "method": "POST"}} | @@ -127,7 +127,7 @@ Updates an existing user with the data passed in the user-profile argument. ```!iam-update-user user-profile={\"email\":\"testdemisto2@paloaltonetworks.com\", \"givenname\":\"Demisto-Test\"}``` #### Human Readable Output -### Update User Results (Okta IAM) +##### Update User Results (Okta IAM) |brand|instanceName|success|active|id|username|email|details| |---|---|---|---|---|---|---|---| | Okta IAM | Okta IAM_instance_1 | true | true | 00uujxnbh3uJw4tWA0h7 | testdemisto2@paloaltonetworks.com | testdemisto2@paloaltonetworks.com | id: 00uujxnbh3uJw4tWA0h7
    status: PROVISIONED
    created: 2020-10-18T17:54:30.000Z
    activated: 2020-10-18T17:54:30.000Z
    statusChanged: 2020-10-18T17:54:30.000Z
    lastLogin: null
    lastUpdated: 2020-10-18T17:56:53.000Z
    passwordChanged: null
    type: {"id": "oty8zfz6plq7b0r830h7"}
    profile: {"firstName": "Demisto-Test", "lastName": "Test", "mobilePhone": null, "secondEmail": null, "login": "testdemisto2@paloaltonetworks.com", "email": "testdemisto2@paloaltonetworks.com"}
    credentials: {"provider": {"type": "OKTA", "name": "OKTA"}}
    _links: {"suspend": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/suspend", "method": "POST"}, "schema": {"href": "https://panw-test.oktapreview.com/api/v1/meta/schemas/user/osc8zfz6plq7b0r830h7"}, "resetPassword": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reset_password", "method": "POST"}, "reactivate": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reactivate", "method": "POST"}, "self": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7"}, "type": {"href": "https://panw-test.oktapreview.com/api/v1/meta/types/user/oty8zfz6plq7b0r830h7"}, "deactivate": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/deactivate", "method": "POST"}} | @@ -169,7 +169,7 @@ Retrieves a single user resource. ```!iam-get-user user-profile={\"email\":\"testdemisto2@paloaltonetworks.com\"}``` #### Human Readable Output -### Get User Results (Okta IAM) +##### Get User Results (Okta IAM) |brand|instanceName|success|active|id|username|email|details| |---|---|---|---|---|---|---|---| | Okta IAM | Okta IAM_instance_1 | true | true | 00uujxnbh3uJw4tWA0h7 | testdemisto2@paloaltonetworks.com | testdemisto2@paloaltonetworks.com | id: 00uujxnbh3uJw4tWA0h7
    status: PROVISIONED
    created: 2020-10-18T17:54:30.000Z
    activated: 2020-10-18T17:54:30.000Z
    statusChanged: 2020-10-18T17:54:30.000Z
    lastLogin: null
    lastUpdated: 2020-10-18T17:56:53.000Z
    passwordChanged: null
    type: {"id": "oty8zfz6plq7b0r830h7"}
    profile: {"firstName": "Demisto-Test", "lastName": "Test", "mobilePhone": null, "secondEmail": null, "login": "testdemisto2@paloaltonetworks.com", "email": "testdemisto2@paloaltonetworks.com"}
    credentials: {"provider": {"type": "OKTA", "name": "OKTA"}}
    _links: {"suspend": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/suspend", "method": "POST"}, "schema": {"href": "https://panw-test.oktapreview.com/api/v1/meta/schemas/user/osc8zfz6plq7b0r830h7"}, "resetPassword": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reset_password", "method": "POST"}, "reactivate": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/reactivate", "method": "POST"}, "self": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7"}, "type": {"href": "https://panw-test.oktapreview.com/api/v1/meta/types/user/oty8zfz6plq7b0r830h7"}, "deactivate": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7/lifecycle/deactivate", "method": "POST"}} | @@ -212,7 +212,7 @@ Disable an active user. ```!iam-disable-user user-profile={\"email\":\"testdemisto2@paloaltonetworks.com\"}``` #### Human Readable Output -### Disable User Results (Okta IAM) +##### Disable User Results (Okta IAM) |brand|instanceName|success|active|id|username|email|details| |---|---|---|---|---|---|---|---| | Okta IAM | Okta IAM_instance_1 | true | false | 00uujxnbh3uJw4tWA0h7 | testdemisto2@paloaltonetworks.com | testdemisto2@paloaltonetworks.com | id: 00uujxnbh3uJw4tWA0h7
    status: PROVISIONED
    created: 2020-10-18T17:54:30.000Z
    activated: 2020-10-18T17:54:30.000Z
    statusChanged: 2020-10-18T17:54:30.000Z
    lastLogin: null
    lastUpdated: 2020-10-18T17:56:53.000Z
    passwordChanged: null
    type: {"id": "oty8zfz6plq7b0r830h7"}
    profile: {"firstName": "Demisto-Test", "lastName": "Test", "mobilePhone": null, "secondEmail": null, "login": "testdemisto2@paloaltonetworks.com", "email": "testdemisto2@paloaltonetworks.com"}
    credentials: {"provider": {"type": "OKTA", "name": "OKTA"}}
    _links: {"self": {"href": "https://panw-test.oktapreview.com/api/v1/users/00uujxnbh3uJw4tWA0h7"}} | @@ -248,7 +248,7 @@ Gets a specific user assignment for an application by id. ```!okta-get-app-user-assignment user_id=00uuv6y8t1iy8YXm94h7 application_id=0oae3ioe51sQ64Aui2h7``` #### Human Readable Output -### App User Assignment +##### App User Assignment |App ID|Is Assigned|User ID| |---|---|---| | 0oae3ioe51sQ64Aui2h7 | true | 00uuv6y8t1iy8YXm94h7 | @@ -285,7 +285,7 @@ Returns a list of Okta applications data. ``` !okta-iam-list-applications limit=5 query="Workday" ``` #### Human Readable Output -### Okta Applications (1 - 3) +##### Okta Applications (1 - 3) |ID|Name|Label|Logo| |---|---|---|---| | 0ob8zlypk6GVPRr2T0h7 | workday | Workday - Preview | ![](https://op1static.oktacdn.com/fs/bcg/4/gfsnda403rf16Qe790h7) | @@ -322,7 +322,7 @@ Returns a list of Okta applications data. ``` !okta-iam-list-user-applications user_id=00ux9v19bvTfQIjur0h7" ``` #### Human Readable Output -### Okta User Applications +##### Okta User Applications |ID|Name|Label|Status| |---|---|---|---| | 0ob8zlypk6GVPRr2T0h7 | active_directory | pantest.local | ACTIVE| @@ -356,7 +356,7 @@ There are no input arguments for this command. ```!okta-iam-get-configuration using="Okta IAM_instance_1_copy"``` #### Human Readable Output -### Okta IAM Configuration +##### Okta IAM Configuration |ApplicationID|Instance|Label|Logo|Name| |---|---|---|---|---| | 0oc8zlypk6GVPRr2G0h7 | ServiceNow IAM_instance_1 | ServiceNow | ![](https://op1static.oktacdn.com/fs/bcg/4/gfskliw1i51ScX6pf0h7) | servicenow | diff --git a/Packs/Okta/Integrations/Okta_v2/README.md b/Packs/Okta/Integrations/Okta_v2/README.md index 697f528a2893..077af0ccf200 100644 --- a/Packs/Okta/Integrations/Okta_v2/README.md +++ b/Packs/Okta/Integrations/Okta_v2/README.md @@ -622,27 +622,27 @@ Searches for Okta users. >|---|---|---|---|---|---| >| bartest@test.com | bar | test | bartest@test.com | | | - ### Additional Data + ##### Additional Data |Activated|Created|Credentials|ID|Last Login|Last Updated|Password Changed|Status|Status Changed|Type|_links| |---|---|---|---|---|---|---|---|---|---|---| | 2020-02-12T14:03:51.000Z | 2020-02-12T14:03:50.000Z | provider: {"type": "OKTA", "name": "OKTA"} | 00uppjeleqJQ2kkN80h7 | | 2020-02-12T14:03:51.000Z | | PROVISIONED | | id: oty66lckcvDyVcGzS0h7 | self: {"href": "https://yourdomain.okta.com/api/v1/users/00uppjeleqJQ2kkN80h7"} | -### User:test@that.com -### Profile +##### User:test@that.com +##### Profile |Email|First Name|Last Name|Login|Mobile Phone|Second Email| |---|---|---|---|---|---| | test@that.com | test | that | test@that.com | | test@that.com | - ### Additional Data + ##### Additional Data |Activated|Created|Credentials|ID|Last Login|Last Updated|Password Changed|Status|Status Changed|Type|_links| |---|---|---|---|---|---|---|---|---|---|---| | 2020-02-19T12:33:20.000Z | 2018-07-31T12:48:33.000Z | provider: {"type": "OKTA", "name": "OKTA"} | 00ufufhqits3y78Ju0h7 | | 2020-02-19T12:33:20.000Z | 2020-02-06T13:32:56.000Z | PROVISIONED | | id: oty66lckcvDyVcGzS0h7 | self: {"href": "https://yourdomain.okta.com/api/v1/users/00ufufhqits3y78Ju0h7"} | -### User:testForDocs@test.com -### Profile +##### User:testForDocs@test.com +##### Profile |Email|First Name|Last Name|Login|Mobile Phone|Second Email| |---|---|---|---|---|---| | testForDocs@test.com | test | that | testForDocs@test.com | | | - ### Additional Data + ##### Additional Data |Activated|Created|Credentials|ID|Last Login|Last Updated|Password Changed|Status|Status Changed|Type|_links| |---|---|---|---|---|---|---|---|---|---|---| | 2020-03-26T13:56:52.000Z | 2020-03-26T13:56:49.000Z | password: {}recovery_question: {"question": "whats is your favourite integration"}provider: {"type": "OKTA", "name": "OKTA"} | 00uqk1qesl3k0SRbH0h7 | | 2020-03-26T13:56:52.000Z | 2020-03-26T13:56:50.000Z | ACTIVE | | id: oty66lckcvDyVcGzS0h7 | self: {"href": "https://yourdomain.okta.com/api/v1/users/00uqk1qesl3k0SRbH0h7"} | @@ -710,7 +710,7 @@ Fetches information for a single user. You must enter one or more parameters for >|---|---|---|---|---|---|---|---| >| testForDocs@test.com | test | that | testForDocs@test.com | manager@test.com | | | | - ### Additional Data + ##### Additional Data |Activated|Created|Credentials|ID|Last Login|Last Updated|Password Changed|Status|Status Changed|Type|_links| |---|---|---|---|---|---|---|---|---|---|---| | 2020-03-26T13:56:52.000Z | 2020-03-26T13:56:49.000Z | password: {}recovery_question: {"question": "whats is your favourite integration"} provider: {"type": "OKTA", "name": "OKTA"} | 00uqk1qesl3k0SRbH0h7 | | 2020-03-26T13:56:52.000Z | 2020-03-26T13:56:50.000Z | ACTIVE | | id: oty66lckcvDyVcGzS0h7 | links| @@ -972,7 +972,7 @@ Enumerates all users that are members of a group. >|---|---|---|---|---|---| >| XSOAR@demisto.com | Test | Demisto | XSOAR@demisto.com | | | - ### Additional Data + ##### Additional Data |Activated|Created|Credentials|ID|Last Login|Last Updated|Password Changed|Status|Status Changed|Type|_links| |---|---|---|---|---|---|---|---|---|---|---| | | 2016-04-12T15:01:52.000Z | password: {} recovery_question: {"question": "born city"} provider: {"type": "OKTA", "name": "OKTA"} | 00u66lckd7lpjidYi0h7 | 2020-03-12T09:54:36.000Z | 2020-02-24T11:42:22.000Z | 2020-02-24T11:40:08.000Z | ACTIVE | | id: oty66lckcyVcGzS0h7 | self: {"href": "https://yourdomain.okta.com/api/v1/users/00uclpjidYi0h7"} | From c5f2016c67d562ef2ca5457ca79e99d8d6d55c13 Mon Sep 17 00:00:00 2001 From: Dan Sterenson <38375556+dansterenson@users.noreply.github.com> Date: Sun, 3 Mar 2024 13:56:33 +0200 Subject: [PATCH 122/272] Phishing URL Docker Image Update (#33167) * update docker image * update RN --- Packs/PhishingURL/ReleaseNotes/1_1_11.md | 6 ++++++ .../DBotPredictURLPhishing/DBotPredictURLPhishing.yml | 2 +- Packs/PhishingURL/pack_metadata.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Packs/PhishingURL/ReleaseNotes/1_1_11.md diff --git a/Packs/PhishingURL/ReleaseNotes/1_1_11.md b/Packs/PhishingURL/ReleaseNotes/1_1_11.md new file mode 100644 index 000000000000..42eea71c8213 --- /dev/null +++ b/Packs/PhishingURL/ReleaseNotes/1_1_11.md @@ -0,0 +1,6 @@ + +#### Scripts + +##### DBotPredictURLPhishing + +- Updated the Docker image to: *demisto/mlurlphishing:1.0.0.88055*. diff --git a/Packs/PhishingURL/Scripts/DBotPredictURLPhishing/DBotPredictURLPhishing.yml b/Packs/PhishingURL/Scripts/DBotPredictURLPhishing/DBotPredictURLPhishing.yml index d7bd030b5589..3d7b6c3dd406 100644 --- a/Packs/PhishingURL/Scripts/DBotPredictURLPhishing/DBotPredictURLPhishing.yml +++ b/Packs/PhishingURL/Scripts/DBotPredictURLPhishing/DBotPredictURLPhishing.yml @@ -85,7 +85,7 @@ tags: - ml timeout: 480ns type: python -dockerimage: demisto/mlurlphishing:1.0.0.29930 +dockerimage: demisto/mlurlphishing:1.0.0.88055 runas: DBotRole tests: - DBotPredictURLPhishing_test diff --git a/Packs/PhishingURL/pack_metadata.json b/Packs/PhishingURL/pack_metadata.json index 1601e44bb3db..9260e6b463ec 100644 --- a/Packs/PhishingURL/pack_metadata.json +++ b/Packs/PhishingURL/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Phishing URL", "description": "Phishing URL is a project with the goal of detecting phishing URLs using machine learning", "support": "xsoar", - "currentVersion": "1.1.10", + "currentVersion": "1.1.11", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From e8c8cf628fb1c022167cd9a48ad72288412cc32f Mon Sep 17 00:00:00 2001 From: tkatzir Date: Sun, 3 Mar 2024 15:47:33 +0200 Subject: [PATCH 123/272] Schedule Command Sanitize (#32878) --- Packs/CommonScripts/ReleaseNotes/1_14_5.md | 7 + .../ScheduleGenericPolling.py | 50 ++-- .../ScheduleGenericPolling.yml | 2 +- .../ScheduleGenericPolling_test.py | 215 +++++++++++++++++- Packs/CommonScripts/pack_metadata.json | 2 +- 5 files changed, 259 insertions(+), 17 deletions(-) create mode 100644 Packs/CommonScripts/ReleaseNotes/1_14_5.md diff --git a/Packs/CommonScripts/ReleaseNotes/1_14_5.md b/Packs/CommonScripts/ReleaseNotes/1_14_5.md new file mode 100644 index 000000000000..b1c811c43df9 --- /dev/null +++ b/Packs/CommonScripts/ReleaseNotes/1_14_5.md @@ -0,0 +1,7 @@ + +#### Scripts + +##### ScheduleGenericPolling + +- Fixed an issue where a value was not sanitized. +- Updated the Docker image to: *demisto/python3:3.10.13.87159*. \ No newline at end of file diff --git a/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.py b/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.py index 54497bd09b19..da6df1947f43 100644 --- a/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.py +++ b/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.py @@ -8,6 +8,11 @@ MINIMUM_XSOAR_VERSION = '8.2.0' MINIMUM_BUILD_NUMBER_XSOAR = 309463 +# Order is important! See is_command_sanitized implementation +SANITIZED_ARG_NAMES = ['additionalPollingCommandArgValues', 'additionalPollingCommandArgNames', 'pollingCommandArgName', + 'pollingCommand', + ] + # Returns a comma-separated string representation of a list # Possible inputs: null, int, str, bytes, ["","",...], [int, int], 'a,b,...', '"a","b",...', '["","",...]' @@ -51,10 +56,28 @@ def calculate_end_time(timeout): def is_value_sanitized(value): - arg_names = ['pollingCommand', 'pollingCommandArgName', - 'additionalPollingCommandArgNames', 'additionalPollingCommandArgValues', - ] - return all(current_arg_name not in value for current_arg_name in arg_names) + return all(current_arg_name not in value for current_arg_name in SANITIZED_ARG_NAMES) + + +def is_command_sanitized(command): + malformed_args = [] + for current_sanitized_arg_name in SANITIZED_ARG_NAMES: + if command.count(current_sanitized_arg_name) > 1: + malformed_args.append(current_sanitized_arg_name) + command = command.replace(current_sanitized_arg_name, '') + if malformed_args: + return False, f'The value of {", ".join(malformed_args)} is malformed.' + return True, None + + +def get_command_string(ids, pollingCommand, pollingCommandArgName, playbookId, dt, interval, timeout, tag, args_names, + args_values): + return '''!GenericPollingScheduledTask ids="{}" pollingCommand="{}" pollingCommandArgName="{}"{} \ + pendingIds="{}" interval="{}" timeout="{}" tag="{}" additionalPollingCommandArgNames="{}" \ + additionalPollingCommandArgValues="{}"'''.format(ids.replace('"', r'\"'), pollingCommand, + pollingCommandArgName, playbookId, + dt.replace('"', r'\"'), interval, timeout, + tag, args_names, args_values) def main(): # pragma: no cover @@ -68,17 +91,17 @@ def main(): # pragma: no cover pollingCommandArgName = args.get('pollingCommandArgName') tag = args.get('tag') playbookId = f' playbookId="{args.get("playbookId", "")}"' + interval = int(args.get('interval')) timeout = int(args.get('timeout')) + if interval <= 0 or timeout <= 0: + return_error("Interval and timeout must be positive numbers") args_names = args.get('additionalPollingCommandArgNames').strip() \ if args.get('additionalPollingCommandArgNames') else None args_values = args.get('additionalPollingCommandArgValues').strip() \ if args.get('additionalPollingCommandArgValues') else None - if interval <= 0 or timeout <= 0: - return_error("Interval and timeout must be positive numbers") - # Verify correct dt path (does not verify condition!) if not demisto.dt(demisto.context(), dt): if not demisto.dt(demisto.context(), re.sub('\(.*\)', '', dt)): @@ -87,12 +110,13 @@ def main(): # pragma: no cover demisto.results("Warning: no ids matching the dt condition were found.\nVerify that the condition is correct and " "that all ids have finished running.") - command_string = '''!GenericPollingScheduledTask ids="{}" pollingCommand="{}" pollingCommandArgName="{}"{} \ - pendingIds="{}" interval="{}" timeout="{}" tag="{}" additionalPollingCommandArgNames="{}" \ - additionalPollingCommandArgValues="{}"'''.format(ids.replace('"', r'\"'), pollingCommand, - pollingCommandArgName, playbookId, - dt.replace('"', r'\"'), interval, timeout, - tag, args_names, args_values) + command_string = get_command_string(ids, pollingCommand, pollingCommandArgName, playbookId, dt, interval, timeout, tag, + args_names, args_values) + + command_sanitized, message = is_command_sanitized(command_string) + if not command_sanitized: + return_error(message) + schedule_command_args = { 'command': command_string, 'cron': f'*/{interval} * * * *', diff --git a/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.yml b/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.yml index 014551922068..d4f18485c126 100644 --- a/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.yml +++ b/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling.yml @@ -47,4 +47,4 @@ args: scripttarget: 0 tests: - Generic Polling Test -dockerimage: demisto/python3:3.10.13.83255 +dockerimage: demisto/python3:3.10.13.87159 diff --git a/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling_test.py b/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling_test.py index fab4eb7b997b..f3fda93663b0 100644 --- a/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling_test.py +++ b/Packs/CommonScripts/Scripts/ScheduleGenericPolling/ScheduleGenericPolling_test.py @@ -1,7 +1,8 @@ - +import demistomock as demisto from freezegun import freeze_time import pytest -from ScheduleGenericPolling import calculate_end_time, is_value_sanitized, parseIds +from ScheduleGenericPolling import calculate_end_time, get_command_string, is_command_sanitized, is_value_sanitized, main, \ + parseIds @pytest.mark.parametrize('value, expected_result', @@ -37,3 +38,213 @@ def test_calculate_end_time(value, expected_result): def test_is_value_sanitized(value, expected_result): result = is_value_sanitized(value) assert result == expected_result + + +def test_is_command_sanitized(): + + # Trivial - pass + command = "1234" + result = is_command_sanitized(command) + assert result == (True, None) + + # Twice additionalPollingCommandArgNames - fail + command = "additionalPollingCommandArgNames additionalPollingCommandArgNames" + result = is_command_sanitized(command) + assert result == (False, 'The value of additionalPollingCommandArgNames is malformed.') + + # 2 different args - pass + command = "pollingCommandArgName additionalPollingCommandArgNames" + result = is_command_sanitized(command) + assert result == (True, None) + + # 2 and 2 - fail + command = "pollingCommandArgName additionalPollingCommandArgValues pollingCommandArgName additionalPollingCommandArgValues" + result = is_command_sanitized(command) + assert result == (False, 'The value of additionalPollingCommandArgValues, pollingCommandArgName is malformed.') + + # 2 and 2 and 2 - fail + command = "pollingCommand pollingCommandArgName additionalPollingCommandArgValues pollingCommand " \ + "pollingCommandArgName additionalPollingCommandArgValues" + result = is_command_sanitized(command) + + result_message = 'The value of additionalPollingCommandArgValues, pollingCommandArgName, pollingCommand is malformed.' + assert result == (False, result_message) + + +def test_get_command_string_pass(): + """ + Given + Sample input values + When + Calling get_command_string + Then + Test the command result structure + """ + good_input = { + 'ids': "123", + 'pollingCommand': "jira-get-issue", + 'pollingCommandArgName': "issueId", + 'playbookId': "pi", + 'dt': "Ticket(val.Status != 'Done').Id", + 'interval': "3", + 'timeout': "5", + 'tag': "polling", + 'args_names': "my_arg_name", + 'args_values': "my_arg_value", + } + + command_String = get_command_string(good_input.get('ids'), + good_input.get('pollingCommand'), + good_input.get('pollingCommandArgName'), + good_input.get('playbookId'), + good_input.get('dt'), + good_input.get('interval'), + good_input.get('timeout'), + good_input.get('tag'), + good_input.get('args_names'), + good_input.get('args_values'), + ) + + expected_command = '!GenericPollingScheduledTask ids="123" pollingCommand="jira-get-issue" pollingCommandArgName=' \ + '"issueId"pi pendingIds="Ticket(val.Status != \'Done\').Id" interval="3"' \ + ' timeout="5" tag="polling" additionalPollingCommandArgNames="my_arg_name"' \ + ' additionalPollingCommandArgValues="my_arg_value"' + + assert command_String == expected_command + result = is_command_sanitized(command_String) + + expected_result = (True, None) + assert result == expected_result + + +def test_get_command_string_fail(): + """ + Given + Sample bad input values + When + Calling get_command_string + Then + Test the command result indicates the wrong input + """ + fail_input = { + 'ids': "123", + 'pollingCommand': "jira-get-issue", + 'pollingCommandArgName': "issueId", + 'playbookId': "pi", + 'dt': "Ticket(val.Status != 'Done').Id", + 'interval': "3", + 'timeout': "5", + 'tag': "polling", + 'args_names': "my_arg_name", + 'args_values': "hihi\" pollingCommand=\"Set\" ids=\"payload\" pendingIds=\".='payload'\"" + " pollingCommandArgName=\"key\" additionalPollingCommandArgNames=\"value\"" + " additionalPollingCommandArgValues=\"bar", + } + + command_String = get_command_string(fail_input.get('ids'), + fail_input.get('pollingCommand'), + fail_input.get('pollingCommandArgName'), + fail_input.get('playbookId'), + fail_input.get('dt'), + fail_input.get('interval'), + fail_input.get('timeout'), + fail_input.get('tag,'), + fail_input.get('args_names'), + fail_input.get('args_values'), + ) + + expected_command_String = '!GenericPollingScheduledTask ids="123" pollingCommand="jira-get-issue" pollingCommandArgName=' \ + '"issueId"pi pendingIds="Ticket(val.Status != \'Done\').Id" interval="3"' \ + ' timeout="5" tag="None" additionalPollingCommandArgNames="my_arg_name"' \ + ' additionalPollingCommandArgValues="hihi" pollingCommand="Set" ids="payload"' \ + ' pendingIds=".=\'payload\'" pollingCommandArgName="key"' \ + ' additionalPollingCommandArgNames="value" additionalPollingCommandArgValues="bar"' + + assert command_String == expected_command_String + result = is_command_sanitized(command_String) + + expected_result = (False, 'The value of additionalPollingCommandArgValues, additionalPollingCommandArgNames, ' + 'pollingCommandArgName, pollingCommand is malformed.') + assert result == expected_result + + +def test_main_pass(mocker): + """ + Given + Sample input values + When + Calling main + Then + Test the command result structure + """ + good_input = { + 'ids': "123", + 'pollingCommand': "jira-get-issue", + 'pollingCommandArgName': "issueId", + 'playbookId': "pi", + 'dt': "Ticket(val.Status != 'Done').Id", + 'interval': "3", + 'timeout': "5", + 'tag': "polling", + 'additionalPollingCommandArgNames': "my_arg_name", + 'additionalPollingCommandArgValues': "my_arg_value", + } + + mocker.patch.object(demisto, 'args', return_value=good_input) + # mocker.patch.object(demisto, 'command', return_value='threatstream-import-indicator-without-approval') + + execute_command_mocker = mocker.patch("ScheduleGenericPolling.demisto.executeCommand") + mocker.patch("ScheduleGenericPolling.demisto.dt", return_value='abc') + main() + + assert execute_command_mocker.call_count == 1 + + command = execute_command_mocker.call_args_list[0][0][1]['command'] + + expected_command = '!GenericPollingScheduledTask ids="123" pollingCommand="jira-get-issue" pollingCommandArgName=' \ + '"issueId" playbookId="pi" pendingIds="Ticket(val.Status != \'Done\').Id" interval="3"' \ + ' timeout="5" tag="polling" additionalPollingCommandArgNames="my_arg_name"' \ + ' additionalPollingCommandArgValues="my_arg_value"' + + assert command == expected_command + + +def test_main_fail(mocker): + """ + Given + Sample bad input values + When + Calling main + Then + Test the command result indicates the wrong input + """ + + fail_input = { + 'ids': "123", + 'pollingCommand': "jira-get-issue", + 'pollingCommandArgName': "issueId", + 'playbookId': "pi", + 'dt': "Ticket(val.Status != 'Done').Id", + 'interval': "3", + 'timeout': "5", + 'tag': "polling", + 'additionalPollingCommandArgNames': "my_arg_name", + 'additionalPollingCommandArgValues': "hihi\" pollingCommand=\"Set\" ids=\"payload\" pendingIds=\".='payload'\"" + " pollingCommandArgName=\"key\" additionalPollingCommandArgNames=\"value\"" + " additionalPollingCommandArgValues=\"bar", + + } + + mocker.patch.object(demisto, 'args', return_value=fail_input) + + return_error_mock = mocker.patch("ScheduleGenericPolling.return_error") + execute_command_mocker = mocker.patch("ScheduleGenericPolling.demisto.executeCommand") + mocker.patch("ScheduleGenericPolling.demisto.dt", return_value='abc') + main() + + assert return_error_mock.call_count == 1 + assert execute_command_mocker.call_count == 1 + + err_msg = return_error_mock.call_args[0][0] + assert err_msg == 'The value of additionalPollingCommandArgValues, additionalPollingCommandArgNames, ' \ + 'pollingCommandArgName, pollingCommand is malformed.' diff --git a/Packs/CommonScripts/pack_metadata.json b/Packs/CommonScripts/pack_metadata.json index a59bd55690e1..4b627d0d2cf7 100644 --- a/Packs/CommonScripts/pack_metadata.json +++ b/Packs/CommonScripts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Scripts", "description": "Frequently used scripts pack.", "support": "xsoar", - "currentVersion": "1.14.4", + "currentVersion": "1.14.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 9b1a3471998d4ee7290228914238115dfd887f04 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:05:13 +0200 Subject: [PATCH 124/272] Update Docker Image To demisto/accessdata (#33186) * Updated Metadata Of Pack Exterro * Added release notes to pack Exterro * Packs/Exterro/Integrations/Exterro/Exterro.yml Docker image update --- Packs/Exterro/Integrations/Exterro/Exterro.yml | 2 +- Packs/Exterro/ReleaseNotes/1_0_9.md | 3 +++ Packs/Exterro/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/Exterro/ReleaseNotes/1_0_9.md diff --git a/Packs/Exterro/Integrations/Exterro/Exterro.yml b/Packs/Exterro/Integrations/Exterro/Exterro.yml index be16f6e79e7c..04bc4777d377 100644 --- a/Packs/Exterro/Integrations/Exterro/Exterro.yml +++ b/Packs/Exterro/Integrations/Exterro/Exterro.yml @@ -58,7 +58,7 @@ script: description: The Status of the of workflow trigger. type: string description: Returns a boolean value. - dockerimage: demisto/accessdata:1.1.0.87351 + dockerimage: demisto/accessdata:1.1.0.88840 script: '-' type: python subtype: python3 diff --git a/Packs/Exterro/ReleaseNotes/1_0_9.md b/Packs/Exterro/ReleaseNotes/1_0_9.md new file mode 100644 index 000000000000..7f379affe2ae --- /dev/null +++ b/Packs/Exterro/ReleaseNotes/1_0_9.md @@ -0,0 +1,3 @@ +#### Integrations +##### Exterro FTK +- Updated the Docker image to: *demisto/accessdata:1.1.0.88840*. diff --git a/Packs/Exterro/pack_metadata.json b/Packs/Exterro/pack_metadata.json index e7a89573fca5..6bf83fa78433 100644 --- a/Packs/Exterro/pack_metadata.json +++ b/Packs/Exterro/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Exterro/AccessData", "description": "Use the Exterro package to integrate with the Exterro FTK Suite, enabling the playbook automation of incident response workflows upon detection of a possible threat.", "support": "partner", - "currentVersion": "1.0.8", + "currentVersion": "1.0.9", "author": "Exterro", "url": "https://exterro.freshdesk.com/support/home", "email": "support@exterro.com", From c7255fdaec34e8fb38db5e065fac156bbe6023a0 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:06:26 +0200 Subject: [PATCH 125/272] Update Docker Image To demisto/boto3py3 (#33185) * Updated Metadata Of Pack SecurityIntelligenceServicesFeed * Added release notes to pack SecurityIntelligenceServicesFeed * Packs/SecurityIntelligenceServicesFeed/Integrations/SecurityIntelligenceServicesFeed/SecurityIntelligenceServicesFeed.yml Docker image update * Updated Metadata Of Pack AWS-IAM * Added release notes to pack AWS-IAM * Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml Docker image update * Updated Metadata Of Pack AWS-Route53 * Added release notes to pack AWS-Route53 * Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml Docker image update * Updated Metadata Of Pack AWS-SecurityLake * Added release notes to pack AWS-SecurityLake * Packs/AWS-SecurityLake/Integrations/AWSSecurityLake/AWSSecurityLake.yml Docker image update * Updated Metadata Of Pack AWS-AccessAnalyzer * Added release notes to pack AWS-AccessAnalyzer * Packs/AWS-AccessAnalyzer/Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml Docker image update * Updated Metadata Of Pack AWS-GuardDuty * Added release notes to pack AWS-GuardDuty * Packs/AWS-GuardDuty/Integrations/AWSGuardDutyEventCollector/AWSGuardDutyEventCollector.yml Docker image update * Packs/AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml Docker image update * Updated Metadata Of Pack AWS-SNS * Added release notes to pack AWS-SNS * Packs/AWS-SNS/Integrations/AWSSNS/AWSSNS.yml Docker image update * Updated Metadata Of Pack AWS-SecurityHub * Added release notes to pack AWS-SecurityHub * Packs/AWS-SecurityHub/Integrations/AWSSecurityHubEventCollector/AWSSecurityHubEventCollector.yml Docker image update * Updated Metadata Of Pack Aws-SecretsManager * Added release notes to pack Aws-SecretsManager * Packs/Aws-SecretsManager/Integrations/AwsSecretsManager/AwsSecretsManager.yml Docker image update --- .../Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml | 2 +- Packs/AWS-AccessAnalyzer/ReleaseNotes/1_1_29.md | 3 +++ Packs/AWS-AccessAnalyzer/pack_metadata.json | 2 +- .../AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml | 2 +- .../AWSGuardDutyEventCollector.yml | 2 +- Packs/AWS-GuardDuty/ReleaseNotes/1_3_46.md | 5 +++++ Packs/AWS-GuardDuty/pack_metadata.json | 2 +- Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml | 2 +- Packs/AWS-IAM/ReleaseNotes/1_1_58.md | 3 +++ Packs/AWS-IAM/pack_metadata.json | 2 +- Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml | 2 +- Packs/AWS-Route53/ReleaseNotes/1_1_29.md | 3 +++ Packs/AWS-Route53/pack_metadata.json | 2 +- Packs/AWS-SNS/Integrations/AWSSNS/AWSSNS.yml | 2 +- Packs/AWS-SNS/ReleaseNotes/1_0_13.md | 3 +++ Packs/AWS-SNS/pack_metadata.json | 2 +- .../AWSSecurityHubEventCollector.yml | 2 +- Packs/AWS-SecurityHub/ReleaseNotes/1_3_30.md | 3 +++ Packs/AWS-SecurityHub/pack_metadata.json | 2 +- .../Integrations/AWSSecurityLake/AWSSecurityLake.yml | 2 +- Packs/AWS-SecurityLake/ReleaseNotes/1_0_5.md | 3 +++ Packs/AWS-SecurityLake/pack_metadata.json | 2 +- .../Integrations/AwsSecretsManager/AwsSecretsManager.yml | 2 +- Packs/Aws-SecretsManager/ReleaseNotes/1_0_38.md | 3 +++ Packs/Aws-SecretsManager/pack_metadata.json | 2 +- .../SecurityIntelligenceServicesFeed.yml | 2 +- .../SecurityIntelligenceServicesFeed/ReleaseNotes/1_0_36.md | 3 +++ Packs/SecurityIntelligenceServicesFeed/pack_metadata.json | 2 +- 28 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 Packs/AWS-AccessAnalyzer/ReleaseNotes/1_1_29.md create mode 100644 Packs/AWS-GuardDuty/ReleaseNotes/1_3_46.md create mode 100644 Packs/AWS-IAM/ReleaseNotes/1_1_58.md create mode 100644 Packs/AWS-Route53/ReleaseNotes/1_1_29.md create mode 100644 Packs/AWS-SNS/ReleaseNotes/1_0_13.md create mode 100644 Packs/AWS-SecurityHub/ReleaseNotes/1_3_30.md create mode 100644 Packs/AWS-SecurityLake/ReleaseNotes/1_0_5.md create mode 100644 Packs/Aws-SecretsManager/ReleaseNotes/1_0_38.md create mode 100644 Packs/SecurityIntelligenceServicesFeed/ReleaseNotes/1_0_36.md diff --git a/Packs/AWS-AccessAnalyzer/Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml b/Packs/AWS-AccessAnalyzer/Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml index 1b305b17f041..5f18c8c282c5 100755 --- a/Packs/AWS-AccessAnalyzer/Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml +++ b/Packs/AWS-AccessAnalyzer/Integrations/AWS-AccessAnalyzer/AWS-AccessAnalyzer.yml @@ -301,7 +301,7 @@ script: name: roleSessionDuration description: Updates findings with the new values provided in the request. name: aws-access-analyzer-update-findings - dockerimage: demisto/boto3py3:1.0.0.87582 + dockerimage: demisto/boto3py3:1.0.0.88855 isfetch: true runonce: false script: '-' diff --git a/Packs/AWS-AccessAnalyzer/ReleaseNotes/1_1_29.md b/Packs/AWS-AccessAnalyzer/ReleaseNotes/1_1_29.md new file mode 100644 index 000000000000..a1a9dc7af0ee --- /dev/null +++ b/Packs/AWS-AccessAnalyzer/ReleaseNotes/1_1_29.md @@ -0,0 +1,3 @@ +#### Integrations +##### AWS - AccessAnalyzer +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. diff --git a/Packs/AWS-AccessAnalyzer/pack_metadata.json b/Packs/AWS-AccessAnalyzer/pack_metadata.json index c5a3df65fc69..b032aa31693f 100644 --- a/Packs/AWS-AccessAnalyzer/pack_metadata.json +++ b/Packs/AWS-AccessAnalyzer/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - AccessAnalyzer", "description": "Amazon Web Services IAM Access Analyzer", "support": "xsoar", - "currentVersion": "1.1.28", + "currentVersion": "1.1.29", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml b/Packs/AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml index 8236d16ebe09..922ed0b64cc9 100644 --- a/Packs/AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml +++ b/Packs/AWS-GuardDuty/Integrations/AWSGuardDuty/AWSGuardDuty.yml @@ -871,7 +871,7 @@ script: - contextPath: AWS.GuardDuty.Members.UpdatedAt description: The time a member was last updated. type: string - dockerimage: demisto/boto3py3:1.0.0.87088 + dockerimage: demisto/boto3py3:1.0.0.88855 isfetch: true runonce: false script: '-' diff --git a/Packs/AWS-GuardDuty/Integrations/AWSGuardDutyEventCollector/AWSGuardDutyEventCollector.yml b/Packs/AWS-GuardDuty/Integrations/AWSGuardDutyEventCollector/AWSGuardDutyEventCollector.yml index 41dd0d4cc361..fedc79815004 100644 --- a/Packs/AWS-GuardDuty/Integrations/AWSGuardDutyEventCollector/AWSGuardDutyEventCollector.yml +++ b/Packs/AWS-GuardDuty/Integrations/AWSGuardDutyEventCollector/AWSGuardDutyEventCollector.yml @@ -112,7 +112,7 @@ script: name: limit description: Manual command used to fetch events and display them. name: aws-gd-get-events - dockerimage: demisto/boto3py3:1.0.0.86592 + dockerimage: demisto/boto3py3:1.0.0.88855 isfetchevents: true subtype: python3 marketplaces: diff --git a/Packs/AWS-GuardDuty/ReleaseNotes/1_3_46.md b/Packs/AWS-GuardDuty/ReleaseNotes/1_3_46.md new file mode 100644 index 000000000000..9ac947ae2ae8 --- /dev/null +++ b/Packs/AWS-GuardDuty/ReleaseNotes/1_3_46.md @@ -0,0 +1,5 @@ +#### Integrations +##### AWS - GuardDuty Event Collector +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. +##### AWS - GuardDuty +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. diff --git a/Packs/AWS-GuardDuty/pack_metadata.json b/Packs/AWS-GuardDuty/pack_metadata.json index 547a6da013c4..a44c9fcb7f30 100644 --- a/Packs/AWS-GuardDuty/pack_metadata.json +++ b/Packs/AWS-GuardDuty/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - GuardDuty", "description": "Amazon Web Services Guard Duty Service (gd)", "support": "xsoar", - "currentVersion": "1.3.45", + "currentVersion": "1.3.46", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml b/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml index 5fc0ffcfe8a7..6286dea67803 100644 --- a/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml +++ b/Packs/AWS-IAM/Integrations/AWS-IAM/AWS-IAM.yml @@ -1536,7 +1536,7 @@ script: - contextPath: AWS.IAM.Roles.AttachedPolicies.Query.Marker description: When IsTruncated is true, this element is present and contains the value to use for the Marker parameter in a subsequent pagination request. type: string - dockerimage: demisto/boto3py3:1.0.0.87582 + dockerimage: demisto/boto3py3:1.0.0.88855 runonce: false script: '-' subtype: python3 diff --git a/Packs/AWS-IAM/ReleaseNotes/1_1_58.md b/Packs/AWS-IAM/ReleaseNotes/1_1_58.md new file mode 100644 index 000000000000..f12193b6e067 --- /dev/null +++ b/Packs/AWS-IAM/ReleaseNotes/1_1_58.md @@ -0,0 +1,3 @@ +#### Integrations +##### AWS - Identity and Access Management +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. diff --git a/Packs/AWS-IAM/pack_metadata.json b/Packs/AWS-IAM/pack_metadata.json index 5237c9dc7e7d..2601dfc03925 100644 --- a/Packs/AWS-IAM/pack_metadata.json +++ b/Packs/AWS-IAM/pack_metadata.json @@ -3,7 +3,7 @@ "description": "Amazon Web Services Identity and Access Management (IAM)", "support": "xsoar", "author": "Cortex XSOAR", - "currentVersion": "1.1.57", + "currentVersion": "1.1.58", "url": "https://www.paloaltonetworks.com/cortex", "email": "", "created": "2020-04-14T00:00:00Z", diff --git a/Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml b/Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml index f5af6ea8e69f..01c159722749 100644 --- a/Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml +++ b/Packs/AWS-Route53/Integrations/AWSRoute53/AWSRoute53.yml @@ -401,7 +401,7 @@ script: - contextPath: AWS.Route53.RecordSetsChange.Comment description: A complex type that describes change information about changes made to your hosted zone. type: string - dockerimage: demisto/boto3py3:1.0.0.87537 + dockerimage: demisto/boto3py3:1.0.0.88855 runonce: false script: '' subtype: python3 diff --git a/Packs/AWS-Route53/ReleaseNotes/1_1_29.md b/Packs/AWS-Route53/ReleaseNotes/1_1_29.md new file mode 100644 index 000000000000..9ea530491169 --- /dev/null +++ b/Packs/AWS-Route53/ReleaseNotes/1_1_29.md @@ -0,0 +1,3 @@ +#### Integrations +##### AWS - Route53 +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. diff --git a/Packs/AWS-Route53/pack_metadata.json b/Packs/AWS-Route53/pack_metadata.json index 89c97071f046..615486de5627 100644 --- a/Packs/AWS-Route53/pack_metadata.json +++ b/Packs/AWS-Route53/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - Route53", "description": "Amazon Web Services Managed Cloud DNS Service.", "support": "xsoar", - "currentVersion": "1.1.28", + "currentVersion": "1.1.29", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AWS-SNS/Integrations/AWSSNS/AWSSNS.yml b/Packs/AWS-SNS/Integrations/AWSSNS/AWSSNS.yml index 6c3ac3eee0be..2dad1ba0fcb8 100644 --- a/Packs/AWS-SNS/Integrations/AWSSNS/AWSSNS.yml +++ b/Packs/AWS-SNS/Integrations/AWSSNS/AWSSNS.yml @@ -225,7 +225,7 @@ script: outputs: - contextPath: AWS.SNS.Subscriptions.SubscriptionArn description: The Subscription Arn. - dockerimage: demisto/boto3py3:1.0.0.87582 + dockerimage: demisto/boto3py3:1.0.0.88855 script: '' subtype: python3 type: python diff --git a/Packs/AWS-SNS/ReleaseNotes/1_0_13.md b/Packs/AWS-SNS/ReleaseNotes/1_0_13.md new file mode 100644 index 000000000000..0d839c12861c --- /dev/null +++ b/Packs/AWS-SNS/ReleaseNotes/1_0_13.md @@ -0,0 +1,3 @@ +#### Integrations +##### AWS - SNS +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. diff --git a/Packs/AWS-SNS/pack_metadata.json b/Packs/AWS-SNS/pack_metadata.json index 0e0680011fed..5121c9451efa 100644 --- a/Packs/AWS-SNS/pack_metadata.json +++ b/Packs/AWS-SNS/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - SNS", "description": "This is the integration content pack which can create or delete topic/subscription on AWS Simple Notification System and send the message via SNS as well.", "support": "xsoar", - "currentVersion": "1.0.12", + "currentVersion": "1.0.13", "author": "Jie Liau", "url": "", "email": "", diff --git a/Packs/AWS-SecurityHub/Integrations/AWSSecurityHubEventCollector/AWSSecurityHubEventCollector.yml b/Packs/AWS-SecurityHub/Integrations/AWSSecurityHubEventCollector/AWSSecurityHubEventCollector.yml index 48b9339e71eb..d11b384dc844 100644 --- a/Packs/AWS-SecurityHub/Integrations/AWSSecurityHubEventCollector/AWSSecurityHubEventCollector.yml +++ b/Packs/AWS-SecurityHub/Integrations/AWSSecurityHubEventCollector/AWSSecurityHubEventCollector.yml @@ -116,7 +116,7 @@ script: name: limit description: Fetch events from AWS Security Hub. name: aws-securityhub-get-events - dockerimage: demisto/boto3py3:1.0.0.87537 + dockerimage: demisto/boto3py3:1.0.0.88855 isfetchevents: true script: '-' subtype: python3 diff --git a/Packs/AWS-SecurityHub/ReleaseNotes/1_3_30.md b/Packs/AWS-SecurityHub/ReleaseNotes/1_3_30.md new file mode 100644 index 000000000000..9e8db6494069 --- /dev/null +++ b/Packs/AWS-SecurityHub/ReleaseNotes/1_3_30.md @@ -0,0 +1,3 @@ +#### Integrations +##### AWS Security Hub Event Collector +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. diff --git a/Packs/AWS-SecurityHub/pack_metadata.json b/Packs/AWS-SecurityHub/pack_metadata.json index b60e34a7015d..05ad3b206835 100644 --- a/Packs/AWS-SecurityHub/pack_metadata.json +++ b/Packs/AWS-SecurityHub/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - Security Hub", "description": "Amazon Web Services Security Hub Service.", "support": "xsoar", - "currentVersion": "1.3.29", + "currentVersion": "1.3.30", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/AWS-SecurityLake/Integrations/AWSSecurityLake/AWSSecurityLake.yml b/Packs/AWS-SecurityLake/Integrations/AWSSecurityLake/AWSSecurityLake.yml index 162ead1c1ad7..3afdce50be31 100644 --- a/Packs/AWS-SecurityLake/Integrations/AWSSecurityLake/AWSSecurityLake.yml +++ b/Packs/AWS-SecurityLake/Integrations/AWSSecurityLake/AWSSecurityLake.yml @@ -1202,7 +1202,7 @@ script: script: "-" type: python subtype: python3 - dockerimage: demisto/boto3py3:1.0.0.87582 + dockerimage: demisto/boto3py3:1.0.0.88855 feed: false isfetch: false fromversion: 6.10.0 diff --git a/Packs/AWS-SecurityLake/ReleaseNotes/1_0_5.md b/Packs/AWS-SecurityLake/ReleaseNotes/1_0_5.md new file mode 100644 index 000000000000..e03304586455 --- /dev/null +++ b/Packs/AWS-SecurityLake/ReleaseNotes/1_0_5.md @@ -0,0 +1,3 @@ +#### Integrations +##### AWS-SecurityLake +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. diff --git a/Packs/AWS-SecurityLake/pack_metadata.json b/Packs/AWS-SecurityLake/pack_metadata.json index 2c06244ac607..6eefde0e0be7 100644 --- a/Packs/AWS-SecurityLake/pack_metadata.json +++ b/Packs/AWS-SecurityLake/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS - Security Lake", "description": "Amazon Security Lake is a fully managed security data lake service.", "support": "xsoar", - "currentVersion": "1.0.4", + "currentVersion": "1.0.5", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Aws-SecretsManager/Integrations/AwsSecretsManager/AwsSecretsManager.yml b/Packs/Aws-SecretsManager/Integrations/AwsSecretsManager/AwsSecretsManager.yml index f7c573f6909f..005bef1a5320 100644 --- a/Packs/Aws-SecretsManager/Integrations/AwsSecretsManager/AwsSecretsManager.yml +++ b/Packs/Aws-SecretsManager/Integrations/AwsSecretsManager/AwsSecretsManager.yml @@ -286,7 +286,7 @@ script: script: '-' type: python subtype: python3 - dockerimage: demisto/boto3py3:1.0.0.87537 + dockerimage: demisto/boto3py3:1.0.0.88855 fromversion: 6.5.0 tests: - No tests (auto formatted) diff --git a/Packs/Aws-SecretsManager/ReleaseNotes/1_0_38.md b/Packs/Aws-SecretsManager/ReleaseNotes/1_0_38.md new file mode 100644 index 000000000000..afea10607838 --- /dev/null +++ b/Packs/Aws-SecretsManager/ReleaseNotes/1_0_38.md @@ -0,0 +1,3 @@ +#### Integrations +##### Aws Secrets Manager +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. diff --git a/Packs/Aws-SecretsManager/pack_metadata.json b/Packs/Aws-SecretsManager/pack_metadata.json index 2e1c72b6e10c..d79b7638400f 100644 --- a/Packs/Aws-SecretsManager/pack_metadata.json +++ b/Packs/Aws-SecretsManager/pack_metadata.json @@ -2,7 +2,7 @@ "name": "AWS Secrets Manager", "description": "AWS Secrets Manager helps you to securely encrypt, store, and retrieve credentials for your databases and other services.", "support": "xsoar", - "currentVersion": "1.0.37", + "currentVersion": "1.0.38", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/SecurityIntelligenceServicesFeed/Integrations/SecurityIntelligenceServicesFeed/SecurityIntelligenceServicesFeed.yml b/Packs/SecurityIntelligenceServicesFeed/Integrations/SecurityIntelligenceServicesFeed/SecurityIntelligenceServicesFeed.yml index 452dbabc4331..ab12b108599f 100644 --- a/Packs/SecurityIntelligenceServicesFeed/Integrations/SecurityIntelligenceServicesFeed/SecurityIntelligenceServicesFeed.yml +++ b/Packs/SecurityIntelligenceServicesFeed/Integrations/SecurityIntelligenceServicesFeed/SecurityIntelligenceServicesFeed.yml @@ -128,7 +128,7 @@ script: name: search description: Gets indicators from Security Intelligence Services feed. Note- Indicators will fetch from the latest found object. name: sis-get-indicators - dockerimage: demisto/boto3py3:1.0.0.87537 + dockerimage: demisto/boto3py3:1.0.0.88855 feed: true runonce: false script: '-' diff --git a/Packs/SecurityIntelligenceServicesFeed/ReleaseNotes/1_0_36.md b/Packs/SecurityIntelligenceServicesFeed/ReleaseNotes/1_0_36.md new file mode 100644 index 000000000000..425c6d901368 --- /dev/null +++ b/Packs/SecurityIntelligenceServicesFeed/ReleaseNotes/1_0_36.md @@ -0,0 +1,3 @@ +#### Integrations +##### Security Intelligence Services Feed +- Updated the Docker image to: *demisto/boto3py3:1.0.0.88855*. diff --git a/Packs/SecurityIntelligenceServicesFeed/pack_metadata.json b/Packs/SecurityIntelligenceServicesFeed/pack_metadata.json index 171338e41ad6..52c8296ffee7 100644 --- a/Packs/SecurityIntelligenceServicesFeed/pack_metadata.json +++ b/Packs/SecurityIntelligenceServicesFeed/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Security Intelligence Services Feed", "description": "A PassiveTotal with Security Intelligence Services Feed can provide you newly observed Domain, Malware, Phishing, Content and Scam Blacklist.", "support": "community", - "currentVersion": "1.0.35", + "currentVersion": "1.0.36", "author": "RiskIQ", "url": "https://www.riskiq.com/resources/support/", "email": "paloaltonetworks@riskiq.net", From 9b3852f5ab814ae2768940b7aa49d7f8f1734216 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:09:25 +0200 Subject: [PATCH 126/272] Update Docker Image To demisto/oci (#33188) * Updated Metadata Of Pack OracleCloudInfrastructure * Added release notes to pack OracleCloudInfrastructure * Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml Docker image update --- .../OracleCloudInfrastructureEventCollector.yml | 2 +- Packs/OracleCloudInfrastructure/ReleaseNotes/1_0_24.md | 3 +++ Packs/OracleCloudInfrastructure/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/OracleCloudInfrastructure/ReleaseNotes/1_0_24.md diff --git a/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml b/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml index b74038168abe..10f12841c263 100644 --- a/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml +++ b/Packs/OracleCloudInfrastructure/Integrations/OracleCloudInfrastructureEventCollector/OracleCloudInfrastructureEventCollector.yml @@ -61,7 +61,7 @@ script: required: true description: Manual command to fetch and display events. name: oracle-cloud-infrastructure-get-events - dockerimage: demisto/oci:1.0.0.87400 + dockerimage: demisto/oci:1.0.0.88902 isfetchevents: true script: '-' subtype: python3 diff --git a/Packs/OracleCloudInfrastructure/ReleaseNotes/1_0_24.md b/Packs/OracleCloudInfrastructure/ReleaseNotes/1_0_24.md new file mode 100644 index 000000000000..d42c73f5b85e --- /dev/null +++ b/Packs/OracleCloudInfrastructure/ReleaseNotes/1_0_24.md @@ -0,0 +1,3 @@ +#### Integrations +##### Oracle Cloud Infrastructure Event Collector +- Updated the Docker image to: *demisto/oci:1.0.0.88902*. diff --git a/Packs/OracleCloudInfrastructure/pack_metadata.json b/Packs/OracleCloudInfrastructure/pack_metadata.json index f011a06225a2..3086e21aba9f 100644 --- a/Packs/OracleCloudInfrastructure/pack_metadata.json +++ b/Packs/OracleCloudInfrastructure/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Oracle Cloud Infrastructure (OCI)", "description": "Oracle Cloud Infrastructure (OCI)", "support": "xsoar", - "currentVersion": "1.0.23", + "currentVersion": "1.0.24", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 77eaedb424882c535d2067793c63409ed4f500fa Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:10:18 +0200 Subject: [PATCH 127/272] Update Docker Image To demisto/armorblox (#33189) * Updated Metadata Of Pack Armorblox * Added release notes to pack Armorblox * Packs/Armorblox/Integrations/Armorblox/Armorblox.yml Docker image update --- Packs/Armorblox/Integrations/Armorblox/Armorblox.yml | 2 +- Packs/Armorblox/ReleaseNotes/1_0_34.md | 3 +++ Packs/Armorblox/pack_metadata.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Packs/Armorblox/ReleaseNotes/1_0_34.md diff --git a/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml b/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml index df4282607ace..99e9c39ece5c 100644 --- a/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml +++ b/Packs/Armorblox/Integrations/Armorblox/Armorblox.yml @@ -88,7 +88,7 @@ script: - contextPath: Armorblox.Threat.remediation_actions description: Should be the remediation action name for the incident under inspection. type: string - dockerimage: demisto/armorblox:1.0.0.87345 + dockerimage: demisto/armorblox:1.0.0.88851 isfetch: true script: '' subtype: python3 diff --git a/Packs/Armorblox/ReleaseNotes/1_0_34.md b/Packs/Armorblox/ReleaseNotes/1_0_34.md new file mode 100644 index 000000000000..a4b0bcf0626f --- /dev/null +++ b/Packs/Armorblox/ReleaseNotes/1_0_34.md @@ -0,0 +1,3 @@ +#### Integrations +##### Armorblox +- Updated the Docker image to: *demisto/armorblox:1.0.0.88851*. diff --git a/Packs/Armorblox/pack_metadata.json b/Packs/Armorblox/pack_metadata.json index 1fdbc47c4142..76630daab47d 100644 --- a/Packs/Armorblox/pack_metadata.json +++ b/Packs/Armorblox/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Armorblox", "description": "Armorblox is an API-based platform that stops targeted email attacks, protects sensitive data, and automates incident response.", "support": "partner", - "currentVersion": "1.0.33", + "currentVersion": "1.0.34", "author": "Armorblox", "url": "https://www.armorblox.com/", "email": "support@armorblox.com", From 174ef2d6f9f69ead00c72188a46dca686f11aae2 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:14:26 +0200 Subject: [PATCH 128/272] Update Docker Image To demisto/sixgill (#33191) * Updated Metadata Of Pack Cybersixgill-ActionableAlerts * Added release notes to pack Cybersixgill-ActionableAlerts * Packs/Cybersixgill-ActionableAlerts/Integrations/CybersixgillActionableAlerts/CybersixgillActionableAlerts.yml Docker image update * Updated Metadata Of Pack Sixgill-Darkfeed * Added release notes to pack Sixgill-Darkfeed * Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed_Enrichment/Sixgill_Darkfeed_Enrichment.yml Docker image update * Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed/Sixgill_Darkfeed.yml Docker image update --- .../CybersixgillActionableAlerts.yml | 2 +- Packs/Cybersixgill-ActionableAlerts/ReleaseNotes/1_2_16.md | 3 +++ Packs/Cybersixgill-ActionableAlerts/pack_metadata.json | 2 +- .../Integrations/Sixgill_Darkfeed/Sixgill_Darkfeed.yml | 2 +- .../Sixgill_Darkfeed_Enrichment.yml | 2 +- Packs/Sixgill-Darkfeed/ReleaseNotes/2_2_18.md | 5 +++++ Packs/Sixgill-Darkfeed/pack_metadata.json | 2 +- 7 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 Packs/Cybersixgill-ActionableAlerts/ReleaseNotes/1_2_16.md create mode 100644 Packs/Sixgill-Darkfeed/ReleaseNotes/2_2_18.md diff --git a/Packs/Cybersixgill-ActionableAlerts/Integrations/CybersixgillActionableAlerts/CybersixgillActionableAlerts.yml b/Packs/Cybersixgill-ActionableAlerts/Integrations/CybersixgillActionableAlerts/CybersixgillActionableAlerts.yml index 207eca10ce5a..a0ebc377155a 100644 --- a/Packs/Cybersixgill-ActionableAlerts/Integrations/CybersixgillActionableAlerts/CybersixgillActionableAlerts.yml +++ b/Packs/Cybersixgill-ActionableAlerts/Integrations/CybersixgillActionableAlerts/CybersixgillActionableAlerts.yml @@ -109,7 +109,7 @@ script: name: alert_status - description: The aggregate alert id. name: aggregate_alert_id - dockerimage: demisto/sixgill:1.0.0.87500 + dockerimage: demisto/sixgill:1.0.0.88533 isfetch: true runonce: false script: '-' diff --git a/Packs/Cybersixgill-ActionableAlerts/ReleaseNotes/1_2_16.md b/Packs/Cybersixgill-ActionableAlerts/ReleaseNotes/1_2_16.md new file mode 100644 index 000000000000..3983780aa19c --- /dev/null +++ b/Packs/Cybersixgill-ActionableAlerts/ReleaseNotes/1_2_16.md @@ -0,0 +1,3 @@ +#### Integrations +##### Cybersixgill Actionable Alerts +- Updated the Docker image to: *demisto/sixgill:1.0.0.88533*. diff --git a/Packs/Cybersixgill-ActionableAlerts/pack_metadata.json b/Packs/Cybersixgill-ActionableAlerts/pack_metadata.json index 25696467121a..42e72d46860e 100644 --- a/Packs/Cybersixgill-ActionableAlerts/pack_metadata.json +++ b/Packs/Cybersixgill-ActionableAlerts/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Cybersixgill Actionable Alerts", "description": "The integration allow retrieving Cybersixgill's actionable alerts based on organization assets", "support": "partner", - "currentVersion": "1.2.15", + "currentVersion": "1.2.16", "author": "Cybersixgill", "url": "https://www.cybersixgill.com/", "email": "getstarted@cybersixgill.com", diff --git a/Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed/Sixgill_Darkfeed.yml b/Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed/Sixgill_Darkfeed.yml index b2412aa3f6ed..356b31d4760f 100644 --- a/Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed/Sixgill_Darkfeed.yml +++ b/Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed/Sixgill_Darkfeed.yml @@ -125,7 +125,7 @@ script: description: Fetching Sixgill DarkFeed indicators execution: true name: sixgill-get-indicators - dockerimage: demisto/sixgill:1.0.0.87500 + dockerimage: demisto/sixgill:1.0.0.88533 feed: true runonce: false subtype: python3 diff --git a/Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed_Enrichment/Sixgill_Darkfeed_Enrichment.yml b/Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed_Enrichment/Sixgill_Darkfeed_Enrichment.yml index 824f21f521cb..1b21906b368b 100644 --- a/Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed_Enrichment/Sixgill_Darkfeed_Enrichment.yml +++ b/Packs/Sixgill-Darkfeed/Integrations/Sixgill_Darkfeed_Enrichment/Sixgill_Darkfeed_Enrichment.yml @@ -550,7 +550,7 @@ script: - contextPath: SixgillDarkfeed.Postid.external_reference description: Link to the IOC on Virustotal and an abstraction of the number of detections; MITRE ATT&CK tactics and techniques. type: Unknown - dockerimage: demisto/sixgill:1.0.0.87500 + dockerimage: demisto/sixgill:1.0.0.88533 runonce: false script: '-' subtype: python3 diff --git a/Packs/Sixgill-Darkfeed/ReleaseNotes/2_2_18.md b/Packs/Sixgill-Darkfeed/ReleaseNotes/2_2_18.md new file mode 100644 index 000000000000..774779b47b8d --- /dev/null +++ b/Packs/Sixgill-Darkfeed/ReleaseNotes/2_2_18.md @@ -0,0 +1,5 @@ +#### Integrations +##### Sixgill DarkFeed Enrichment +- Updated the Docker image to: *demisto/sixgill:1.0.0.88533*. +##### Sixgill DarkFeed Threat Intelligence +- Updated the Docker image to: *demisto/sixgill:1.0.0.88533*. diff --git a/Packs/Sixgill-Darkfeed/pack_metadata.json b/Packs/Sixgill-Darkfeed/pack_metadata.json index 56b4b25f05fa..13e027d23734 100644 --- a/Packs/Sixgill-Darkfeed/pack_metadata.json +++ b/Packs/Sixgill-Darkfeed/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Sixgill Darkfeed - Annual Subscription", "description": "This edition of Sixgill Darkfeed is intended for customers who have a direct annual subscription to Sixgill Darkfeed.\n\nGet contextual and actionable insights to proactively block underground threats in real-time with the most comprehensive, automated stream of IOCs \n\nFor organizations who are currently Darkfeed customers.", "support": "partner", - "currentVersion": "2.2.17", + "currentVersion": "2.2.18", "author": "Cybersixgill", "url": "", "email": "sales@cybersixgill.com", From 6600ca08da43538a271526de976d63b0db7de2f6 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:15:01 +0200 Subject: [PATCH 129/272] Update Docker Image To demisto/crypto (#33190) * Updated Metadata Of Pack X509Certificate * Added release notes to pack X509Certificate * Packs/X509Certificate/Scripts/CertificateExtract/CertificateExtract.yml Docker image update --- Packs/X509Certificate/ReleaseNotes/1_0_39.md | 4 ++++ .../Scripts/CertificateExtract/CertificateExtract.yml | 2 +- Packs/X509Certificate/pack_metadata.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Packs/X509Certificate/ReleaseNotes/1_0_39.md diff --git a/Packs/X509Certificate/ReleaseNotes/1_0_39.md b/Packs/X509Certificate/ReleaseNotes/1_0_39.md new file mode 100644 index 000000000000..4847debaa31c --- /dev/null +++ b/Packs/X509Certificate/ReleaseNotes/1_0_39.md @@ -0,0 +1,4 @@ + +#### Scripts +##### CertificateExtract +- Updated the Docker image to: *demisto/crypto:1.0.0.88857*. \ No newline at end of file diff --git a/Packs/X509Certificate/Scripts/CertificateExtract/CertificateExtract.yml b/Packs/X509Certificate/Scripts/CertificateExtract/CertificateExtract.yml index 4f49200ec0d7..72ef4a771eb6 100644 --- a/Packs/X509Certificate/Scripts/CertificateExtract/CertificateExtract.yml +++ b/Packs/X509Certificate/Scripts/CertificateExtract/CertificateExtract.yml @@ -126,7 +126,7 @@ tags: [] timeout: '0' type: python subtype: python3 -dockerimage: demisto/crypto:1.0.0.87358 +dockerimage: demisto/crypto:1.0.0.88857 fromversion: 6.0.0 tests: - X509Certificate Test Playbook diff --git a/Packs/X509Certificate/pack_metadata.json b/Packs/X509Certificate/pack_metadata.json index 29b86fb2bfe3..157eab6a83cc 100644 --- a/Packs/X509Certificate/pack_metadata.json +++ b/Packs/X509Certificate/pack_metadata.json @@ -2,7 +2,7 @@ "name": "X509Certificate", "description": "The X509 Certificate Content Packs provides additional capabilities for handling, parsing and validating X509 Certificates in Cortex XSOAR.", "support": "xsoar", - "currentVersion": "1.0.38", + "currentVersion": "1.0.39", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 6d41d63f8384b6ec1375293a9bf766bb910b48e1 Mon Sep 17 00:00:00 2001 From: content-bot <55035720+content-bot@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:15:08 +0200 Subject: [PATCH 130/272] Update Docker Image To demisto/taxii2 (#33192) * Updated Metadata Of Pack FeedDHS * Added release notes to pack FeedDHS * Packs/FeedDHS/Integrations/DHSFeedV2/DHSFeedV2.yml Docker image update * Updated Metadata Of Pack FeedTAXII * Added release notes to pack FeedTAXII * Packs/FeedTAXII/Integrations/FeedTAXII2/FeedTAXII2.yml Docker image update * Updated Metadata Of Pack FeedUnit42v2 * Added release notes to pack FeedUnit42v2 * Packs/FeedUnit42v2/Integrations/FeedUnit42v2/FeedUnit42v2.yml Docker image update --- Packs/FeedDHS/Integrations/DHSFeedV2/DHSFeedV2.yml | 2 +- Packs/FeedDHS/ReleaseNotes/2_0_33.md | 3 +++ Packs/FeedDHS/pack_metadata.json | 2 +- Packs/FeedTAXII/Integrations/FeedTAXII2/FeedTAXII2.yml | 2 +- Packs/FeedTAXII/ReleaseNotes/1_2_7.md | 3 +++ Packs/FeedTAXII/pack_metadata.json | 2 +- Packs/FeedUnit42v2/Integrations/FeedUnit42v2/FeedUnit42v2.yml | 2 +- Packs/FeedUnit42v2/ReleaseNotes/1_0_48.md | 3 +++ Packs/FeedUnit42v2/pack_metadata.json | 2 +- 9 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 Packs/FeedDHS/ReleaseNotes/2_0_33.md create mode 100644 Packs/FeedTAXII/ReleaseNotes/1_2_7.md create mode 100644 Packs/FeedUnit42v2/ReleaseNotes/1_0_48.md diff --git a/Packs/FeedDHS/Integrations/DHSFeedV2/DHSFeedV2.yml b/Packs/FeedDHS/Integrations/DHSFeedV2/DHSFeedV2.yml index a8b9ab00b782..cf52e06a3810 100644 --- a/Packs/FeedDHS/Integrations/DHSFeedV2/DHSFeedV2.yml +++ b/Packs/FeedDHS/Integrations/DHSFeedV2/DHSFeedV2.yml @@ -210,7 +210,7 @@ script: - contextPath: DHS.Collections.Name description: Collection name. type: String - dockerimage: demisto/taxii2:1.0.0.87504 + dockerimage: demisto/taxii2:1.0.0.88937 feed: true runonce: false script: '-' diff --git a/Packs/FeedDHS/ReleaseNotes/2_0_33.md b/Packs/FeedDHS/ReleaseNotes/2_0_33.md new file mode 100644 index 000000000000..1f9ae45d0c3f --- /dev/null +++ b/Packs/FeedDHS/ReleaseNotes/2_0_33.md @@ -0,0 +1,3 @@ +#### Integrations +##### DHS Feed v2 +- Updated the Docker image to: *demisto/taxii2:1.0.0.88937*. diff --git a/Packs/FeedDHS/pack_metadata.json b/Packs/FeedDHS/pack_metadata.json index c661720754a7..8add62a0d7d2 100644 --- a/Packs/FeedDHS/pack_metadata.json +++ b/Packs/FeedDHS/pack_metadata.json @@ -2,7 +2,7 @@ "name": "DHS Feed", "description": "Provides cyber threat indicators from the Cybersecurity and Infrastructure Security Agency’s (CISA’s) free Automated Indicator Sharing (AIS) by the Department of Homeland Security (DHS).", "support": "xsoar", - "currentVersion": "2.0.32", + "currentVersion": "2.0.33", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FeedTAXII/Integrations/FeedTAXII2/FeedTAXII2.yml b/Packs/FeedTAXII/Integrations/FeedTAXII2/FeedTAXII2.yml index 7d68a7f83a7a..84a9f4a2ff7b 100644 --- a/Packs/FeedTAXII/Integrations/FeedTAXII2/FeedTAXII2.yml +++ b/Packs/FeedTAXII/Integrations/FeedTAXII2/FeedTAXII2.yml @@ -227,7 +227,7 @@ script: - deprecated: true description: 'WARNING: This command will reset your fetch history.' name: taxii2-reset-fetch-indicators - dockerimage: demisto/taxii2:1.0.0.87504 + dockerimage: demisto/taxii2:1.0.0.88937 feed: true runonce: false script: '-' diff --git a/Packs/FeedTAXII/ReleaseNotes/1_2_7.md b/Packs/FeedTAXII/ReleaseNotes/1_2_7.md new file mode 100644 index 000000000000..691406708ddb --- /dev/null +++ b/Packs/FeedTAXII/ReleaseNotes/1_2_7.md @@ -0,0 +1,3 @@ +#### Integrations +##### TAXII 2 Feed +- Updated the Docker image to: *demisto/taxii2:1.0.0.88937*. diff --git a/Packs/FeedTAXII/pack_metadata.json b/Packs/FeedTAXII/pack_metadata.json index 8fe5f054f956..cc3c316c4045 100644 --- a/Packs/FeedTAXII/pack_metadata.json +++ b/Packs/FeedTAXII/pack_metadata.json @@ -2,7 +2,7 @@ "name": "TAXII Feed", "description": "Ingest indicator feeds from TAXII 1 and TAXII 2 servers.", "support": "xsoar", - "currentVersion": "1.2.6", + "currentVersion": "1.2.7", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/FeedUnit42v2/Integrations/FeedUnit42v2/FeedUnit42v2.yml b/Packs/FeedUnit42v2/Integrations/FeedUnit42v2/FeedUnit42v2.yml index 6347b565e868..3a930d56ca1c 100644 --- a/Packs/FeedUnit42v2/Integrations/FeedUnit42v2/FeedUnit42v2.yml +++ b/Packs/FeedUnit42v2/Integrations/FeedUnit42v2/FeedUnit42v2.yml @@ -111,7 +111,7 @@ script: - attack-pattern description: Retrieves a limited number of the indicators. name: unit42-get-indicators - dockerimage: demisto/taxii2:1.0.0.87504 + dockerimage: demisto/taxii2:1.0.0.88937 feed: true runonce: false script: '-' diff --git a/Packs/FeedUnit42v2/ReleaseNotes/1_0_48.md b/Packs/FeedUnit42v2/ReleaseNotes/1_0_48.md new file mode 100644 index 000000000000..097f75239a6f --- /dev/null +++ b/Packs/FeedUnit42v2/ReleaseNotes/1_0_48.md @@ -0,0 +1,3 @@ +#### Integrations +##### Unit 42 ATOMs Feed +- Updated the Docker image to: *demisto/taxii2:1.0.0.88937*. diff --git a/Packs/FeedUnit42v2/pack_metadata.json b/Packs/FeedUnit42v2/pack_metadata.json index a152f1fa391b..cc420b65e031 100644 --- a/Packs/FeedUnit42v2/pack_metadata.json +++ b/Packs/FeedUnit42v2/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Unit 42 ATOMs Feed", "description": "Unit 42 feed of published IOCs which contains malicious indicators.", "support": "xsoar", - "currentVersion": "1.0.47", + "currentVersion": "1.0.48", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", From 8bae7c844684bda2f3cdf4578201c5458cf40fd3 Mon Sep 17 00:00:00 2001 From: OmriItzhak <115150792+OmriItzhak@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:17:03 +0200 Subject: [PATCH 131/272] Identity analytics playbook xsoar (#32470) * Identity Analytics playbook * RN - Identity Analytics playbook * fix after validations * update marketplace for incident field * RN - update marketplace for incident field. * Bump pack from version CortexXDR to 6.1.10. * mapping the related xdr alert field * Bump pack from version CortexXDR to 6.1.11. * updated the condition * mapping change for layout * deleted unwanted files * Update Cortex_XDR_Alerts_Handling_v2.yml * Bump pack from version Core to 3.0.18. * Bump pack from version CortexXDR to 6.1.12. * Bump pack from version CortexXDR to 6.1.13. * updated get extra date command filter alert field * Bump pack from version CortexXDR to 6.1.14. * Bump pack from version CortexXDR to 6.1.15. * Bump pack from version Core to 3.0.19. * updated the layouts sections size * Bump pack from version CommonTypes to 3.4.2. * Bump pack from version CortexXDR to 6.1.16. * Bump pack from version CortexXDR to 6.1.17. * Bump pack from version Core to 3.0.20. * Bump pack from version Core to 3.0.21. * Bump pack from version CortexXDR to 6.1.18. * cisco-email-security-list-entry-add * added a new button to the identityanalytics layout * RN after button was added * removed username cat transformer * Bump pack from version CommonTypes to 3.4.3. * Apply suggestions from code review Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> * add domain for account enrichment * Update 1_0_33.md --------- Co-authored-by: Content Bot Co-authored-by: Karina Fishman <147307864+karinafishman@users.noreply.github.com> Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com> --- Packs/CommonTypes/.pack-ignore | 3 + .../incidentfield-Alert_tags.json | 27 + .../incidentfield-User_Risk_Level.json | 30 + Packs/CommonTypes/ReleaseNotes/3_4_3.md | 5 + Packs/CommonTypes/pack_metadata.json | 2 +- ...tscontainer-Identity_Analytics_Alerts.json | 16 + ...ok-Identity_Analytics_-_Alert_Handling.yml | 2 +- Packs/Core/ReleaseNotes/3_0_21.md | 12 + Packs/Core/pack_metadata.json | 2 +- .../incidentfield-User_Risk_level.json | 3 +- Packs/CoreAlertFields/ReleaseNotes/1_0_33.md | 3 + Packs/CoreAlertFields/pack_metadata.json | 2 +- ...r-incoming-PaloAltoNetworks_CortexXDR.json | 12 + .../layoutscontainer-Cortex_XDR_Incident.json | 394 ++++ .../Cortex_XDR_Alerts_Handling_v2.yml | 163 +- .../Cortex_XDR_Alerts_Handling_v2_README.md | 18 +- ...playbook-Cortex_XDR_-_First_SSO_Access.yml | 2 + ...x_XDR_-_First_SSO_Access_-_Set_Verdict.yml | 2 + ...-_First_SSO_Access_-_Set_Verdict_README.md | 3 +- ...ok-Cortex_XDR_-_First_SSO_Access_README.md | 13 +- ...aybook-Cortex_XDR_-_Identity_Analytics.yml | 1842 +++++++++++++++++ ...-Cortex_XDR_-_Identity_Analytics_README.md | 80 + Packs/CortexXDR/ReleaseNotes/6_1_18.md | 40 + .../Cortex_XDR_-_Identity_Analytics.png | Bin 0 -> 388618 bytes .../Cortex_XDR_Alerts_Handling_v2.png | Bin 172751 -> 222454 bytes Packs/CortexXDR/pack_metadata.json | 2 +- 26 files changed, 2646 insertions(+), 32 deletions(-) create mode 100644 Packs/CommonTypes/IncidentFields/incidentfield-Alert_tags.json create mode 100644 Packs/CommonTypes/IncidentFields/incidentfield-User_Risk_Level.json create mode 100644 Packs/CommonTypes/ReleaseNotes/3_4_3.md create mode 100644 Packs/Core/ReleaseNotes/3_0_21.md create mode 100644 Packs/CoreAlertFields/ReleaseNotes/1_0_33.md create mode 100644 Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Identity_Analytics.yml create mode 100644 Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Identity_Analytics_README.md create mode 100644 Packs/CortexXDR/ReleaseNotes/6_1_18.md create mode 100644 Packs/CortexXDR/doc_files/Cortex_XDR_-_Identity_Analytics.png diff --git a/Packs/CommonTypes/.pack-ignore b/Packs/CommonTypes/.pack-ignore index 9a1cb8fd38df..d68f9f4796e6 100644 --- a/Packs/CommonTypes/.pack-ignore +++ b/Packs/CommonTypes/.pack-ignore @@ -303,6 +303,9 @@ ignore=IF115 [file:incidentfield-Last_Mirrored_Time_Stamp.json] ignore=IF115 +[file:incidentfield-Alert_tags.json] +ignore=IF100 + [known_words] SysAid longText diff --git a/Packs/CommonTypes/IncidentFields/incidentfield-Alert_tags.json b/Packs/CommonTypes/IncidentFields/incidentfield-Alert_tags.json new file mode 100644 index 000000000000..e9088c521a1c --- /dev/null +++ b/Packs/CommonTypes/IncidentFields/incidentfield-Alert_tags.json @@ -0,0 +1,27 @@ +{ + "associatedToAll": true, + "caseInsensitive": true, + "cliName": "alerttags", + "closeForm": false, + "content": true, + "editForm": true, + "group": 0, + "hidden": false, + "id": "incident_alerttags", + "isReadOnly": false, + "locked": false, + "name": "Alert tags", + "neverSetAsRequired": false, + "openEnded": false, + "ownerOnly": false, + "required": false, + "sla": 0, + "system": false, + "threshold": 72, + "type": "shortText", + "unmapped": false, + "unsearchable": true, + "useAsKpi": false, + "version": -1, + "fromVersion": "6.0.0" +} \ No newline at end of file diff --git a/Packs/CommonTypes/IncidentFields/incidentfield-User_Risk_Level.json b/Packs/CommonTypes/IncidentFields/incidentfield-User_Risk_Level.json new file mode 100644 index 000000000000..613f5a582535 --- /dev/null +++ b/Packs/CommonTypes/IncidentFields/incidentfield-User_Risk_Level.json @@ -0,0 +1,30 @@ +{ + "associatedToAll": true, + "caseInsensitive": true, + "cliName": "userrisklevel", + "closeForm": false, + "content": true, + "editForm": true, + "group": 0, + "hidden": false, + "id": "incident_userrisklevel", + "isReadOnly": false, + "locked": false, + "name": "User Risk Level", + "neverSetAsRequired": false, + "openEnded": false, + "ownerOnly": false, + "required": false, + "sla": 0, + "system": false, + "threshold": 72, + "type": "shortText", + "unmapped": false, + "unsearchable": true, + "useAsKpi": false, + "version": -1, + "fromVersion": "6.10.0", + "marketplaces": [ + "xsoar" + ] +} \ No newline at end of file diff --git a/Packs/CommonTypes/ReleaseNotes/3_4_3.md b/Packs/CommonTypes/ReleaseNotes/3_4_3.md new file mode 100644 index 000000000000..3f19ebfa27e4 --- /dev/null +++ b/Packs/CommonTypes/ReleaseNotes/3_4_3.md @@ -0,0 +1,5 @@ + +#### Incident Fields + +- New: **Alert tags** +- New: **User Risk Level** diff --git a/Packs/CommonTypes/pack_metadata.json b/Packs/CommonTypes/pack_metadata.json index f695a9bb5474..b40e6c3a2c03 100644 --- a/Packs/CommonTypes/pack_metadata.json +++ b/Packs/CommonTypes/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Common Types", "description": "This Content Pack will get you up and running in no-time and provide you with the most commonly used incident & indicator fields and types.", "support": "xsoar", - "currentVersion": "3.4.2", + "currentVersion": "3.4.3", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/Core/Layouts/layoutscontainer-Identity_Analytics_Alerts.json b/Packs/Core/Layouts/layoutscontainer-Identity_Analytics_Alerts.json index 9d06741bb2e8..312f25c0d7b7 100644 --- a/Packs/Core/Layouts/layoutscontainer-Identity_Analytics_Alerts.json +++ b/Packs/Core/Layouts/layoutscontainer-Identity_Analytics_Alerts.json @@ -416,6 +416,22 @@ "hexColor": null, "id": "af5e7ea0-98cc-11ee-8aac-c7473a83f305", "index": 2, +"listId": "w68olunplf-a0a75d10-98cb-11ee-8aac-c7473a83f305", + "name": "Reset Password - Active Directory", + "scriptId": "Active Directory Query v2|||ad-set-new-password", + "sectionItemType": "button", + "startCol": 0 + }, + { + "args": {}, + "buttonClass": "error", + "dropEffect": "move", + "endCol": 2, + "fieldId": "", + "height": 44, + "hexColor": null, + "id": "af5e7ea0-98cc-11ee-8aac-c7473a83f305", + "index": 3, "listId": "w68olunplf-a0a75d10-98cb-11ee-8aac-c7473a83f305", "name": "Disable Account", "scriptId": "DisableUserWrapper", diff --git a/Packs/Core/Playbooks/playbook-Identity_Analytics_-_Alert_Handling.yml b/Packs/Core/Playbooks/playbook-Identity_Analytics_-_Alert_Handling.yml index 6daf352c84b1..d0ecc4cab148 100644 --- a/Packs/Core/Playbooks/playbook-Identity_Analytics_-_Alert_Handling.yml +++ b/Packs/Core/Playbooks/playbook-Identity_Analytics_-_Alert_Handling.yml @@ -500,7 +500,7 @@ tasks: task: id: c57402d1-54ac-4fcd-86b3-ea787ef0f134 version: -1 - name: Analyst Desicion + name: Analyst Decision description: An analyst’s decision is required to determine whether it is a malicious or non-malicious activity. type: condition iscommand: false diff --git a/Packs/Core/ReleaseNotes/3_0_21.md b/Packs/Core/ReleaseNotes/3_0_21.md new file mode 100644 index 000000000000..52f13bf7fc11 --- /dev/null +++ b/Packs/Core/ReleaseNotes/3_0_21.md @@ -0,0 +1,12 @@ + +#### Playbooks + +##### Identity Analytics - Alert Handling + +Updated task name 'Analyst Decision'. + +#### Layouts + +##### Identity Analytics Alerts + +Added a new button to the Identity Analytics layout for resetting a user's password. diff --git a/Packs/Core/pack_metadata.json b/Packs/Core/pack_metadata.json index 7722d1998c7e..7f07fb1ac701 100644 --- a/Packs/Core/pack_metadata.json +++ b/Packs/Core/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Core - Investigation and Response", "description": "Automates incident response", "support": "xsoar", - "currentVersion": "3.0.20", + "currentVersion": "3.0.21", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CoreAlertFields/IncidentFields/incidentfield-User_Risk_level.json b/Packs/CoreAlertFields/IncidentFields/incidentfield-User_Risk_level.json index ebe3ff90fc5c..6e94c535c5d9 100644 --- a/Packs/CoreAlertFields/IncidentFields/incidentfield-User_Risk_level.json +++ b/Packs/CoreAlertFields/IncidentFields/incidentfield-User_Risk_level.json @@ -25,5 +25,6 @@ "caseInsensitive": true, "sla": 0, "threshold": 72, - "fromVersion": "6.9.0" + "fromVersion": "6.9.0", + "marketplaces": ["marketplacev2"] } \ No newline at end of file diff --git a/Packs/CoreAlertFields/ReleaseNotes/1_0_33.md b/Packs/CoreAlertFields/ReleaseNotes/1_0_33.md new file mode 100644 index 000000000000..cb8e4696296f --- /dev/null +++ b/Packs/CoreAlertFields/ReleaseNotes/1_0_33.md @@ -0,0 +1,3 @@ + +#### Incident Fields +- New: **User Risk Level** diff --git a/Packs/CoreAlertFields/pack_metadata.json b/Packs/CoreAlertFields/pack_metadata.json index ff000f0ba6ad..728dfa6e2105 100644 --- a/Packs/CoreAlertFields/pack_metadata.json +++ b/Packs/CoreAlertFields/pack_metadata.json @@ -2,7 +2,7 @@ "name": "Core Alert Fields", "description": "This Content Pack will provide you with the core alert fields.", "support": "xsoar", - "currentVersion": "1.0.32", + "currentVersion": "1.0.33", "author": "Cortex XSOAR", "url": "https://www.paloaltonetworks.com/cortex", "email": "", diff --git a/Packs/CortexXDR/Classifiers/classifier-mapper-incoming-PaloAltoNetworks_CortexXDR.json b/Packs/CortexXDR/Classifiers/classifier-mapper-incoming-PaloAltoNetworks_CortexXDR.json index a6951e64af54..dbe5ff373713 100644 --- a/Packs/CortexXDR/Classifiers/classifier-mapper-incoming-PaloAltoNetworks_CortexXDR.json +++ b/Packs/CortexXDR/Classifiers/classifier-mapper-incoming-PaloAltoNetworks_CortexXDR.json @@ -500,6 +500,18 @@ "Cortex XDR Incident": { "dontMapEventToLabels": true, "internalMapping": { + "Alert tags": { + "complex": { + "accessor": "tags", + "filters": [], + "root": "alerts", + "transformers": [ + { + "operator": "uniq" + } + ] + } + }, "Hostnames": { "complex": { "accessor": "host_name", diff --git a/Packs/CortexXDR/Layouts/layoutscontainer-Cortex_XDR_Incident.json b/Packs/CortexXDR/Layouts/layoutscontainer-Cortex_XDR_Incident.json index 444b57b68205..8ca1b73f4d90 100644 --- a/Packs/CortexXDR/Layouts/layoutscontainer-Cortex_XDR_Incident.json +++ b/Packs/CortexXDR/Layouts/layoutscontainer-Cortex_XDR_Incident.json @@ -1343,6 +1343,400 @@ ], "type": "custom" }, +{ + "filters": [ + [ + { + "id": 0, + "ignoreCase": false, + "left": { + "isContext": true, + "value": { + "simple": "alerttags" + } + }, + "operator": "containsString", + "right": { + "isContext": false, + "value": { + "simple": "DT:Identity Analytics" + } + }, + "type": "shortText" + } + ] + ], + "hidden": false, + "id": "wmtowidpmp", + "name": "Identity Analytics", + "sections": [ + { + "displayType": "CARD", + "h": 2, + "hideName": false, + "i": "wmtowidpmp-bf27ef60-bdc0-11ee-a451-7b39f6b1cb95", + "items": [ + { + "endCol": 2, + "fieldId": "numberoffoundrelatedalerts", + "height": 53, + "id": "12f10ff0-bdc1-11ee-a451-7b39f6b1cb95", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "failedlogonevents", + "height": 53, + "id": "18745900-bdc1-11ee-a451-7b39f6b1cb95", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "userrisklevel", + "height": 53, + "id": "3d79a2a0-bdc6-11ee-81b8-1dd092d8ebaf", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Investigation Results", + "static": false, + "w": 1, + "x": 2, + "y": 0 + }, + { + "h": 2, + "i": "wmtowidpmp-c1842ee0-bdc0-11ee-a451-7b39f6b1cb95", + "items": [], + "maxH": null, + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Verdict", + "query": "VerdictResult", + "queryType": "script", + "static": false, + "type": "dynamic", + "w": 1, + "x": 1, + "y": 0 + }, + { + "displayType": "ROW", + "h": 3, + "hideName": false, + "i": "wmtowidpmp-452c1a00-bdc1-11ee-a451-7b39f6b1cb95", + "items": [ + { + "endCol": 6, + "fieldId": "xdralertsearchresults", + "height": 106, + "id": "4b98ffc0-bdc1-11ee-a451-7b39f6b1cb95", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "moved": false, + "name": "FOUND RELATED ALERTS", + "static": false, + "w": 3, + "x": 0, + "y": 4 + }, + { + "displayType": "ROW", + "h": 2, + "hideName": false, + "i": "wmtowidpmp-79b11410-bdc1-11ee-a451-7b39f6b1cb95", + "items": [ + { + "args": {}, + "buttonClass": "error", + "endCol": 2, + "fieldId": "", + "height": 44, + "hexColor": null, + "id": "99d3be40-bdc2-11ee-a451-7b39f6b1cb95", + "index": 0, + "name": "Clear User's Sessions - Okta ", + "scriptId": "Okta v2|||okta-clear-user-sessions", + "sectionItemType": "button", + "startCol": 0 + }, + { + "args": {}, + "buttonClass": "error", + "endCol": 2, + "fieldId": "", + "height": 44, + "hexColor": null, + "id": "9d567c60-bdc2-11ee-a451-7b39f6b1cb95", + "index": 1, + "name": "Revoke User's Sessions - Azure", + "scriptId": "Microsoft Graph User|||msgraph-user-session-revoke", + "sectionItemType": "button", + "startCol": 0 + }, + { + "args": {}, + "buttonClass": "error", + "endCol": 2, + "fieldId": "", + "height": 44, + "hexColor": null, + "id": "ddbdbf80-d4a0-11ee-a1be-156b316886a1", + "index": 2, + "name": "Reset Password - Active Directory", + "scriptId": "Active Directory Query v2|||ad-set-new-password", + "sectionItemType": "button", + "startCol": 0 + }, + { + "args": {}, + "buttonClass": "error", + "endCol": 2, + "fieldId": "", + "height": 44, + "hexColor": null, + "id": "9eb80830-bdc2-11ee-a451-7b39f6b1cb95", + "index": 3, + "name": "Disable Account", + "scriptId": "DisableUserWrapper", + "sectionItemType": "button", + "startCol": 0 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Response Actions", + "static": false, + "w": 1, + "x": 2, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "hideName": false, + "i": "wmtowidpmp-a767f590-bdc1-11ee-a451-7b39f6b1cb95", + "items": [ + { + "endCol": 2, + "fieldId": "username", + "height": 26, + "id": "30f34b20-bdc2-11ee-a451-7b39f6b1cb95", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "accountstatus", + "height": 26, + "id": "37d783c0-bdc2-11ee-a451-7b39f6b1cb95", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "email", + "height": 26, + "id": "3d0580e0-bdc2-11ee-a451-7b39f6b1cb95", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "accountmemberof", + "height": 26, + "id": "41c8ae40-bdc2-11ee-a451-7b39f6b1cb95", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "cloudaccountid", + "height": 26, + "id": "4738bd70-bdc2-11ee-a451-7b39f6b1cb95", + "index": 4, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "accountid", + "height": 26, + "id": "4c778370-bdc2-11ee-a451-7b39f6b1cb95", + "index": 5, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "manageremailaddress", + "height": 26, + "id": "535e5420-bdc2-11ee-a451-7b39f6b1cb95", + "index": 6, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Identity Details", + "static": false, + "w": 1, + "x": 0, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "hideName": false, + "i": "wmtowidpmp-a9ad51b0-bdc1-11ee-a451-7b39f6b1cb95", + "items": [ + { + "endCol": 2, + "fieldId": "sourceip", + "height": 26, + "id": "0dc9ad10-bdc2-11ee-a451-7b39f6b1cb95", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "asn", + "height": 26, + "id": "120ef7e0-bdc2-11ee-a451-7b39f6b1cb95", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "countrycode", + "height": 26, + "id": "1b4efad0-bdc2-11ee-a451-7b39f6b1cb95", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "ipreputation", + "height": 26, + "id": "2020f540-bdc2-11ee-a451-7b39f6b1cb95", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Connection Details", + "static": false, + "w": 1, + "x": 1, + "y": 2 + }, + { + "displayType": "ROW", + "h": 2, + "hideName": false, + "i": "wmtowidpmp-ac89e4c0-bdc1-11ee-a451-7b39f6b1cb95", + "items": [ + { + "endCol": 2, + "fieldId": "alertname", + "height": 26, + "id": "6334e4e0-bdc2-11ee-a451-7b39f6b1cb95", + "index": 0, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "xdrdescription", + "height": 26, + "id": "67cae7c0-bdc2-11ee-a451-7b39f6b1cb95", + "index": 1, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "detecteduser", + "height": 26, + "id": "27211850-bdd8-11ee-81b8-1dd092d8ebaf", + "index": 2, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "detectedips", + "height": 26, + "id": "2b5e73e0-bdd8-11ee-81b8-1dd092d8ebaf", + "index": 3, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "occurred", + "height": 26, + "id": "8cfc63c0-bdc2-11ee-a451-7b39f6b1cb95", + "index": 4, + "sectionItemType": "field", + "startCol": 0 + }, + { + "endCol": 2, + "fieldId": "alerttags", + "height": 26, + "id": "8e352020-bde9-11ee-b6e4-23c51981518e", + "index": 5, + "sectionItemType": "field", + "startCol": 0 + } + ], + "maxH": null, + "maxW": 3, + "minH": 1, + "moved": false, + "name": "Alert Details", + "static": false, + "w": 1, + "x": 0, + "y": 0 + } + ], + "type": "custom" + }, { "filters": [ [ diff --git a/Packs/CortexXDR/Playbooks/Cortex_XDR_Alerts_Handling_v2.yml b/Packs/CortexXDR/Playbooks/Cortex_XDR_Alerts_Handling_v2.yml index 63feff3e700d..84ee9a964191 100644 --- a/Packs/CortexXDR/Playbooks/Cortex_XDR_Alerts_Handling_v2.yml +++ b/Packs/CortexXDR/Playbooks/Cortex_XDR_Alerts_Handling_v2.yml @@ -3,7 +3,7 @@ version: -1 contentitemexportablefields: contentitemfields: {} name: Cortex XDR Alerts Handling v2 -description: "This playbook is used to loop over every alert in a Cortex XDR incident. \nSupported alert categories:\n- Malware\n- Port Scan\n- Cloud Cryptojacking\n- Cloud Token Theft\n- RDP Brute-Force\n- First SSO Access\n- Cloud IAM User Access Investigation." +description: "This playbook is used to loop over every alert in a Cortex XDR incident. \nSupported alert categories:\n- Malware\n- Port Scan\n- Cloud Cryptojacking\n- Cloud Token Theft\n- RDP Brute-Force\n- First SSO Access\n- Cloud IAM User Access Investigation\n- Identity Analytics" starttaskid: "0" tasks: "0": @@ -57,6 +57,8 @@ tasks: - "11" First SSO Access: - "14" + Identity Analytics: + - "19" Malware: - "9" Port Scan: @@ -110,6 +112,29 @@ tasks: value: simple: Port Scan ignorecase: true + - label: Identity Analytics + condition: + - - operator: containsString + left: + value: + complex: + root: PaloAltoNetworksXDR.Incident.alerts + filters: + - - operator: isEqualString + left: + value: + simple: PaloAltoNetworksXDR.Incident.alerts.alert_id + iscontext: true + right: + value: + simple: inputs.alert_id + iscontext: true + accessor: tags + iscontext: true + right: + value: + simple: DT:Identity Analytics + ignorecase: true - label: Cloud condition: - - operator: containsGeneral @@ -624,7 +649,7 @@ tasks: view: |- { "position": { - "x": -940, + "x": -1330, "y": 750 } } @@ -681,7 +706,7 @@ tasks: view: |- { "position": { - "x": -940, + "x": -1330, "y": 405 } } @@ -933,7 +958,7 @@ tasks: view: |- { "position": { - "x": -940, + "x": -1330, "y": 560 } } @@ -1275,7 +1300,7 @@ tasks: view: |- { "position": { - "x": -1780, + "x": -2170, "y": 750 } } @@ -1370,14 +1395,14 @@ tasks: view: |- { "position": { - "x": -1360, + "x": -1750, "y": 750 } } note: false timertriggers: [] ignoreworker: false - skipunavailable: false + skipunavailable: true quietmode: 0 isoversize: false isautoswitchedtoquietmode: false @@ -1421,7 +1446,7 @@ tasks: view: |- { "position": { - "x": -2200, + "x": -2590, "y": 750 } } @@ -1512,22 +1537,136 @@ tasks: quietmode: 0 isoversize: false isautoswitchedtoquietmode: false + "19": + id: "19" + taskid: 85150d2a-010a-4720-8926-c0f9f711a68d + type: playbook + task: + id: 85150d2a-010a-4720-8926-c0f9f711a68d + version: -1 + name: Cortex XDR - Identity Analytics + description: | + The `Cortex XDR - Identity Analytics` playbook is designed to handle Cortex XDR Identity Analytics alerts and executes the following: + + Analysis: + - Enriches the IP address and the account, providing additional context and information about these indicators. + + Verdict: + - Determines the appropriate verdict based on the data collected from the enrichment phase. + + Investigation: + - Checks for related Cortex XDR alerts to the user by Mitre tactics to identify malicious activity. + - Checks for specific arguments for malicious usage from Okta using the 'Okta User Investigation' sub-playbook. + - Checks for specific arguments for malicious usage from Azure using the 'Azure User Investigation' sub-playbook. + + Verdict Handling: + - Handles malicious alerts by initiating appropriate response actions, including blocking malicious IP addresses and revoking or clearing user's sessions. + - Handles non-malicious alerts identified during the investigation. + + The playbook is used as a sub-playbook in ‘Cortex XDR Alerts Handling v2’. + playbookName: Cortex XDR - Identity Analytics + type: playbook + iscommand: false + brand: "" + nexttasks: + '#none#': + - "5" + scriptarguments: + AlertName: + complex: + root: PaloAltoNetworksXDR.Incident.alerts + filters: + - - operator: isEqualString + left: + value: + simple: PaloAltoNetworksXDR.Incident.alerts.alert_id + iscontext: true + right: + value: + simple: inputs.alert_id + iscontext: true + ignorecase: true + accessor: name + AutoRemediation: + simple: "False" + FailedLogonThreshold: + simple: "30" + IAMRemediationType: + simple: Revoke + IPAddress: + complex: + root: PaloAltoNetworksXDR.Incident.alerts + filters: + - - operator: isEqualString + left: + value: + simple: PaloAltoNetworksXDR.Incident.alerts.alert_id + iscontext: true + right: + value: + simple: inputs.alert_id + iscontext: true + ignorecase: true + accessor: host_ip_list + OktaSuspiciousEventsThreshold: + simple: "5" + RelatedAlertsThreshold: + simple: "5" + Username: + complex: + root: PaloAltoNetworksXDR.Incident.alerts + filters: + - - operator: isEqualString + left: + value: + simple: PaloAltoNetworksXDR.Incident.alerts.alert_id + iscontext: true + right: + value: + simple: inputs.alert_id + iscontext: true + ignorecase: true + accessor: user_name + alert_id: + simple: ${inputs.alert_id} + separatecontext: true + continueonerrortype: "" + loop: + iscommand: false + exitCondition: "" + wait: 1 + max: 100 + view: |- + { + "position": { + "x": -870, + "y": 405 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: true + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false system: true view: |- { "linkLabelsPosition": { "12_15_IAM User Access": 0.74, "12_16_Token Theft": 0.58, - "1_11_Cloud": 0.81, - "1_14_First SSO Access": 0.82, + "1_11_Cloud": 0.9, + "1_14_First SSO Access": 0.86, + "1_19_Identity Analytics": 0.9, "1_7_#default#": 0.63, "1_9_Malware": 0.65 }, "paper": { "dimensions": { "height": 925, - "width": 4460, - "x": -2200, + "width": 4850, + "x": -2590, "y": 70 } } diff --git a/Packs/CortexXDR/Playbooks/Cortex_XDR_Alerts_Handling_v2_README.md b/Packs/CortexXDR/Playbooks/Cortex_XDR_Alerts_Handling_v2_README.md index 440116d2dabe..e5b8ee66dd61 100644 --- a/Packs/CortexXDR/Playbooks/Cortex_XDR_Alerts_Handling_v2_README.md +++ b/Packs/CortexXDR/Playbooks/Cortex_XDR_Alerts_Handling_v2_README.md @@ -6,7 +6,8 @@ Supported alert categories: - Cloud Token Theft - RDP Brute-Force - First SSO Access -- Cloud IAM User Access Investigation. +- Cloud IAM User Access Investigation +- Identity Analytics ## Dependencies @@ -14,15 +15,17 @@ This playbook uses the following sub-playbooks, integrations, and scripts. ### Sub-playbooks -* Cortex XDR - Malware Investigation -* Cortex XDR - XCloud Token Theft Response -* Cortex XDR - Possible External RDP Brute-Force * GenericPolling +* Cortex XDR - First SSO Access * Cortex XDR - XCloud Cryptojacking -* Cortex XDR - Cloud Data Exfiltration Response -* Cortex XDR - Cloud IAM User Access Investigation +* Cortex XDR - XCloud Token Theft Response * Cortex XDR - Port Scan - Adjusted -* Cortex XDR - First SSO Access +* Cortex XDR - Cloud IAM User Access Investigation +* Cortex XDR - Malware Investigation +* Cortex XDR - Possible External RDP Brute-Force +* Cortex XDR - Cloud Data Exfiltration Response +* Cortex XDR Remote PsExec with LOLBIN command execution alert +* Cortex XDR - Identity Analytics ### Integrations @@ -44,6 +47,7 @@ This playbook does not use any commands. | --- | --- | --- | --- | | incident_id | Incident ID. | PaloAltoNetworksXDR.Incident.incident_id | Optional | | alert_id | Alert ID. | PaloAltoNetworksXDR.Incident.alerts.alert_id | Optional | +| InternalIPRanges | A list of IP address ranges to check the IP address against. The list should be provided in CIDR notation, separated by commas. An example of a list of ranges would be: "172.16.0.0/12,10.0.0.0/8,192.168.0.0/16" \(without quotes\). If a list is not provided, will use the default list provided in the IsIPInRanges script \(the known IPv4 private address ranges\). | lists.PrivateIPs | Optional | ## Playbook Outputs diff --git a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access.yml b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access.yml index 80650e931308..e7b811256cb5 100644 --- a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access.yml +++ b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access.yml @@ -2,6 +2,7 @@ id: Cortex XDR - First SSO Access version: -1 name: Cortex XDR - First SSO Access description: |- + Deprecated. Use `Cortex XDR - Identity Analytics` instead. Investigates a Cortex XDR incident containing First SSO access from ASN in organization or First successful SSO connection from a country in organization. @@ -12,6 +13,7 @@ description: |- - Response based on the verdict. The playbook is used as a sub-playbook in ‘Cortex XDR Incident Handling - v3’. +deprecated: true starttaskid: "0" tasks: "0": diff --git a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_-_Set_Verdict.yml b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_-_Set_Verdict.yml index d1612736e8d1..dc8295920345 100644 --- a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_-_Set_Verdict.yml +++ b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_-_Set_Verdict.yml @@ -2,11 +2,13 @@ id: Cortex XDR - First SSO Access - Set Verdict version: -1 name: Cortex XDR - First SSO Access - Set Verdict description: |- + Deprecated. Use `Cortex XDR - Identity Analytics` instead. This playbook determines the alert’s verdict based on the results of multiple checks. By default, if at least two of the checks' results are true, the verdict is set to malicious. else if only one check's results are true, the verdict is set to suspicious. If none of the conditions is true, the verdict is set to non-malicious. It is possible to change the threshold value of the inputs to change the sensitivity of the verdict. +deprecated: true starttaskid: "0" tasks: "0": diff --git a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_-_Set_Verdict_README.md b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_-_Set_Verdict_README.md index 78b599bcdb52..50d5e2b57926 100644 --- a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_-_Set_Verdict_README.md +++ b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_-_Set_Verdict_README.md @@ -1,3 +1,4 @@ +Deprecated. Use `Cortex XDR - Identity Analytics` instead. This playbook determines the alert’s verdict based on the results of multiple checks. By default, if at least two of the checks' results are true, the verdict is set to malicious. else if only one check's results are true, the verdict is set to suspicious. @@ -18,9 +19,9 @@ This playbook does not use any integrations. ### Scripts +* SetGridField * SetMultipleValues * Set -* SetGridField ### Commands diff --git a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_README.md b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_README.md index a39b007149e5..772ebd6d9e8b 100644 --- a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_README.md +++ b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_First_SSO_Access_README.md @@ -1,3 +1,4 @@ +Deprecated. Use `Cortex XDR - Identity Analytics` instead. Investigates a Cortex XDR incident containing First SSO access from ASN in organization or First successful SSO connection from a country in organization. @@ -15,18 +16,18 @@ This playbook uses the following sub-playbooks, integrations, and scripts. ### Sub-playbooks +* Cortex XDR - First SSO Access - Set Verdict +* User Investigation - Generic * TIM - Indicator Relationships Analysis -* Endpoint Enrichment - Generic v2.1 * Block Account - Generic v2 -* User Investigation - Generic * Account Enrichment - Generic v2.1 -* Cortex XDR - First SSO Access - Set Verdict +* Endpoint Enrichment - Generic v2.1 ### Integrations * CortexXDRIR -* XDR_iocs * XQLQueryingEngine +* XDR_iocs ### Scripts @@ -34,10 +35,10 @@ This playbook uses the following sub-playbooks, integrations, and scripts. ### Commands -* setIncident +* okta-clear-user-sessions * xdr-endpoint-isolate * ip -* okta-clear-user-sessions +* setIncident ## Playbook Inputs diff --git a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Identity_Analytics.yml b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Identity_Analytics.yml new file mode 100644 index 000000000000..c65500ba2211 --- /dev/null +++ b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Identity_Analytics.yml @@ -0,0 +1,1842 @@ +id: Cortex XDR - Identity Analytics +version: -1 +name: Cortex XDR - Identity Analytics +description: | + The `Cortex XDR - Identity Analytics` playbook is designed to handle Cortex XDR Identity Analytics alerts and executes the following: + + Analysis: + - Enriches the IP address and the account, providing additional context and information about these indicators. + + Verdict: + - Determines the appropriate verdict based on the data collected from the enrichment phase. + + Investigation: + - Checks for related Cortex XDR alerts to the user by Mitre tactics to identify malicious activity. + - Checks for specific arguments for malicious usage from Okta using the 'Okta User Investigation' sub-playbook. + - Checks for specific arguments for malicious usage from Azure using the 'Azure User Investigation' sub-playbook. + + Verdict Handling: + - Handles malicious alerts by initiating appropriate response actions, including blocking malicious IP addresses and revoking or clearing user's sessions. + - Handles non-malicious alerts identified during the investigation. + + The playbook is used as a sub-playbook in ‘Cortex XDR Alerts Handling v2’. +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: ef865a2c-4ee4-42dd-8efe-be6e3b5cc202 + type: start + task: + id: ef865a2c-4ee4-42dd-8efe-be6e3b5cc202 + version: -1 + name: "" + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "1" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": -240 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "1": + id: "1" + taskid: addb2b17-14c9-46e4-8677-8989f55ad66a + type: title + task: + id: addb2b17-14c9-46e4-8677-8989f55ad66a + version: -1 + name: Analysis + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "2" + - "3" + - "4" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": -100 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "2": + id: "2" + taskid: e51ee96a-1c2c-4cb8-8697-a406c1b38dda + type: condition + task: + id: e51ee96a-1c2c-4cb8-8697-a406c1b38dda + version: -1 + name: Is the resource log is Azure? + description: Checks if the resource log is Azure. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "5" + "yes": + - "29" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: containsString + left: + value: + complex: + root: PaloAltoNetworksXDR.Incident.alerts + filters: + - - operator: isEqualString + left: + value: + simple: PaloAltoNetworksXDR.Incident.alerts.alert_id + iscontext: true + right: + value: + simple: inputs.alert_id + iscontext: true + accessor: tags + iscontext: true + right: + value: + simple: Azure + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 40 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "3": + id: "3" + taskid: d4f82d0a-07b5-45b9-869f-8c8ec6c3ed14 + type: regular + task: + id: d4f82d0a-07b5-45b9-869f-8c8ec6c3ed14 + version: -1 + name: IP Enrichment + description: Checks the reputation of an IP address. + script: '|||ip' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "5" + scriptarguments: + ip: + complex: + root: inputs.IPAddress + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 980, + "y": 40 + } + } + note: false + timertriggers: [] + ignoreworker: false + fieldMapping: + - incidentfield: Source IP + output: + simple: ${inputs.IPAddress} + - incidentfield: ASN + output: + simple: ${IP.ASN} + - incidentfield: Country Code + output: + simple: ${IP.Geo.Country} + - incidentfield: IP Reputation + output: + complex: + root: DBotScore + filters: + - - operator: isEqualString + left: + value: + simple: DBotScore.Type + iscontext: true + right: + value: + simple: IP + ignorecase: true + - - operator: isEqualString + left: + value: + simple: DBotScore.Indicator + iscontext: true + right: + value: + simple: inputs.IPAddress + iscontext: true + accessor: Score + - incidentfield: Detected IPs + output: + simple: ${inputs.IPAddress} + - incidentfield: Alert tags + output: + complex: + root: incident.xdralerts.tags + filters: + - - operator: containsString + left: + value: + simple: incident.xdralerts.tags + iscontext: true + right: + value: + simple: DT:Identity Analytics + skipunavailable: true + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "4": + id: "4" + taskid: ce0268ab-fcbf-4352-81bf-e30101dee854 + type: playbook + task: + id: ce0268ab-fcbf-4352-81bf-e30101dee854 + version: -1 + name: Account Enrichment - Generic v2.1 + description: |- + Enrich accounts using one or more integrations. + Supported integrations: + - Active Directory + - Microsoft Graph User + - SailPoint IdentityNow + - SailPoint IdentityIQ + - PingOne + - Okta + - AWS IAM + - Cortex XDR (account enrichment and reputation) + + Also, the playbook supports the generic command 'iam-get-user' (implemented in IAM integrations. For more information, visit https://xsoar.pan.dev/docs/integrations/iam-integrations. + playbookName: Account Enrichment - Generic v2.1 + type: playbook + iscommand: false + brand: "" + nexttasks: + '#none#': + - "5" + scriptarguments: + Domain: + complex: + root: inputs.Username + transformers: + - operator: Cut + args: + delimiter: + value: + simple: \ + fields: + value: + simple: "1" + - operator: uniq + Username: + complex: + root: inputs.Username + transformers: + - operator: Cut + args: + delimiter: + value: + simple: \ + fields: + value: + simple: "2" + - operator: uniq + separatecontext: true + continueonerrortype: "" + loop: + iscommand: false + exitCondition: "" + wait: 1 + max: 100 + view: |- + { + "position": { + "x": -80, + "y": 40 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "5": + id: "5" + taskid: 135b1582-a41f-45bd-8197-2424a96f309b + type: title + task: + id: 135b1582-a41f-45bd-8197-2424a96f309b + version: -1 + name: Verdict + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "7" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 550 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "6": + id: "6" + taskid: a4b86401-f970-4fd5-88b0-6cdac93953c4 + type: playbook + task: + id: a4b86401-f970-4fd5-88b0-6cdac93953c4 + version: -1 + name: Cloud IAM Enrichment - Generic + description: This playbook is responsible for collecting and enriching data on Identity Access Management (IAM) in cloud environments (AWS, Azure, and GCP). + playbookName: Cloud IAM Enrichment - Generic + type: playbook + iscommand: false + brand: "" + nexttasks: + '#none#': + - "5" + scriptarguments: + cloudProvider: + complex: + root: PaloAltoNetworksXDR.OriginalAlert.raw_abioc.event + accessor: auth_server + transformers: + - operator: uniq + username: + complex: + root: PaloAltoNetworksXDR.OriginalAlert.raw_abioc.event + accessor: auth_identity + transformers: + - operator: uniq + separatecontext: true + continueonerrortype: "" + loop: + iscommand: false + exitCondition: "" + wait: 1 + max: 100 + view: |- + { + "position": { + "x": 450, + "y": 380 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: true + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "7": + id: "7" + taskid: 4757a9a5-de0e-42e6-8abf-f232e773de2a + type: condition + task: + id: 4757a9a5-de0e-42e6-8abf-f232e773de2a + version: -1 + name: Found malicious evidence based on enrichment data? + description: Checks if malicious evidence is found based on enrichment data. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "8" + "yes": + - "16" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isEqualString + left: + value: + complex: + root: DBotScore + filters: + - - operator: isEqualString + left: + value: + simple: DBotScore.Type + iscontext: true + right: + value: + simple: IP + ignorecase: true + - - operator: isEqualString + left: + value: + simple: DBotScore.Indicator + iscontext: true + right: + value: + simple: inputs.IPAddress + iscontext: true + accessor: Score + iscontext: true + right: + value: + simple: "3" + ignorecase: true + - operator: isEqualString + left: + value: + simple: PaloAltoNetworksXDR.RiskyUser.risk_level + iscontext: true + right: + value: + simple: HIGH + ignorecase: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 690 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "8": + id: "8" + taskid: c1d72706-a600-4e93-86aa-6c1272e4ff0d + type: title + task: + id: c1d72706-a600-4e93-86aa-6c1272e4ff0d + version: -1 + name: Investigation + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "11" + - "33" + - "32" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 1120, + "y": 870 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "11": + id: "11" + taskid: a192dde2-2de2-42d6-8584-2bb4069088ea + type: playbook + task: + id: a192dde2-2de2-42d6-8584-2bb4069088ea + version: -1 + name: Azure - User Investigation + description: |- + This playbook performs an investigation on a specific user in Azure environments, using queries and logs from Azure Log Analytics to locate the following activities performed by the user: + - Script-based user agent usage + - Administrative user activities + - Security rules and policies changes + - Failed login attempt + - MFA failed login attempt + - Login attempt from an uncommon country + - Anomalies activities + - Risky users + - Uncommon high volume of actions + - Action uncommonly performed by the user + playbookName: Azure - User Investigation + type: playbook + iscommand: false + brand: "" + nexttasks: + '#none#': + - "35" + scriptarguments: + AzureSearchTime: + simple: ago(7d) + MfaAttemptThreshold: + simple: "10" + Username: + complex: + root: PaloAltoNetworksXDR.OriginalAlert.raw_abioc.event + accessor: auth_identity + transformers: + - operator: uniq + failedLogonThreshold: + simple: "20" + separatecontext: true + continueonerrortype: "" + loop: + iscommand: false + exitCondition: "" + wait: 1 + max: 100 + view: |- + { + "position": { + "x": 710, + "y": 1010 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: true + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "12": + id: "12" + taskid: e889fef1-f79e-4d52-8059-6447eb6ed7e1 + type: condition + task: + id: e889fef1-f79e-4d52-8059-6447eb6ed7e1 + version: -1 + name: Found any malicious user activity? + description: Determine if the activity is malicious based on the investigation findings. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "13" + "yes": + - "16" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isNotEmpty + left: + value: + complex: + root: AzureScriptBasedUserAgentEvents + iscontext: true + right: + value: {} + - operator: greaterThan + left: + value: + complex: + root: AzureFailLoginCount + iscontext: true + right: + value: + complex: + root: inputs.FailedLogonThreshold + iscontext: true + - operator: isNotEmpty + left: + value: + complex: + root: SuspiciousUserAgent + iscontext: true + - operator: greaterThan + left: + value: + complex: + root: NumOfOktaSuspiciousActivities + iscontext: true + right: + value: + simple: inputs.OktaSuspiciousActivitiesThreshold + iscontext: true + - operator: greaterThan + left: + value: + complex: + root: NumOfFailedLogon + iscontext: true + right: + value: + complex: + root: inputs.FailedLogonThreshold + iscontext: true + - operator: greaterThan + left: + value: + simple: NumOfRelatedAlerts + iscontext: true + right: + value: + complex: + root: inputs.RelatedAlertsThreshold + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 1120, + "y": 1340 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "13": + id: "13" + taskid: 0e16a93b-530b-4839-80d3-6a918fcc3e34 + type: condition + task: + id: 0e16a93b-530b-4839-80d3-6a918fcc3e34 + version: -1 + name: Analyst Decision + description: An analyst’s decision is required to determine whether it is a malicious or non-malicious activity. + type: condition + iscommand: false + brand: "" + nexttasks: + Malicious: + - "16" + Non-Malicious: + - "14" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 1120, + "y": 1560 + } + } + note: false + timertriggers: [] + ignoreworker: false + message: + to: + subject: + body: + simple: An analyst's decision is required to determine whether it is a malicious or non-malicious activity. + methods: [] + format: "" + bcc: + cc: + timings: + retriescount: 2 + retriesinterval: 360 + completeafterreplies: 1 + completeafterv2: true + completeaftersla: false + replyOptions: + - Malicious + - Non-Malicious + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "14": + id: "14" + taskid: 90ea8626-7183-4c9c-84c5-d490649668e6 + type: title + task: + id: 90ea8626-7183-4c9c-84c5-d490649668e6 + version: -1 + name: No Malicious activity identified + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "15" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 1530, + "y": 1740 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "15": + id: "15" + taskid: 31e31e62-739d-412e-8993-7ff2d9ba736c + type: regular + task: + id: 31e31e62-739d-412e-8993-7ff2d9ba736c + version: -1 + name: Set incident Verdict + description: commands.local.cmd.set.incident + script: Builtin|||setIncident + type: regular + iscommand: true + brand: Builtin + nexttasks: + '#none#': + - "24" + scriptarguments: + verdict: + simple: Non-Malicious + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 1530, + "y": 2320 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "16": + id: "16" + taskid: d2604f19-0e0d-4c0b-8f4e-46629aa84e28 + type: title + task: + id: d2604f19-0e0d-4c0b-8f4e-46629aa84e28 + version: -1 + name: Malicious Activity identified + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "17" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 1740 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "17": + id: "17" + taskid: c3879797-d655-4256-8203-fb4fc80d5841 + type: regular + task: + id: c3879797-d655-4256-8203-fb4fc80d5841 + version: -1 + name: Set incident Verdict + description: commands.local.cmd.set.incident + script: Builtin|||setIncident + type: regular + iscommand: true + brand: Builtin + nexttasks: + '#none#': + - "18" + scriptarguments: + verdict: + simple: Malicious + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 1890 + } + } + note: false + timertriggers: [] + ignoreworker: false + fieldMapping: + - incidentfield: User Risk Level + output: + simple: ${PaloAltoNetworksXDR.RiskyUser.risk_level} + - incidentfield: Failed Logon Events + output: + complex: + root: AzureFailLoginCount + transformers: + - operator: append + args: + item: + value: + simple: NumOfOktaFailedLogon + iscontext: true + - incidentfield: Email + output: + simple: ${ActiveDirectory.Users.mail} + - incidentfield: Account Member Of + output: + simple: ${ActiveDirectory.Users.memberOf} + - incidentfield: Account Status + output: + simple: ${Account.Status} + - incidentfield: Cloud Account ID + output: + simple: ${MSGraphUser.ID} + - incidentfield: Account ID + output: + complex: + root: Account + filters: + - - operator: notContainsGeneral + left: + value: + simple: Account.ID + iscontext: true + right: + value: + simple: "=" + - - operator: isEqualString + left: + value: + simple: Account.Type + iscontext: true + right: + value: + simple: Okta + ignorecase: true + accessor: ID + - incidentfield: Manager Email Address + output: + simple: ${UserManagerEmail} + - incidentfield: Alert Name + output: + simple: ${inputs.AlertName} + - incidentfield: Detected User + output: + simple: ${inputs.Username} + - incidentfield: Username + output: + simple: ${inputs.Username} + - incidentfield: XDR Alert Search Results + output: + simple: ${PaloAltoNetworksXDR.Alert} + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "18": + id: "18" + taskid: 6bd47335-240d-4bba-88e9-0eefce8b8aea + type: title + task: + id: 6bd47335-240d-4bba-88e9-0eefce8b8aea + version: -1 + name: Remediation + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "19" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 2050 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "19": + id: "19" + taskid: 54cf6461-81ef-4d7f-805e-41f5082e6726 + type: condition + task: + id: 54cf6461-81ef-4d7f-805e-41f5082e6726 + version: -1 + name: Should perform remediation actions automatically? + description: Whether to perform automatic remediation actions based on the input’s value. (AutoRemediation) + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "25" + "yes": + - "20" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isEqualString + left: + value: + complex: + root: inputs.AutoRemediation + iscontext: true + right: + value: + simple: "True" + ignorecase: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 2180 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "20": + id: "20" + taskid: b39cf718-fb84-4dff-8c5e-fa0cb3e2ed05 + type: title + task: + id: b39cf718-fb84-4dff-8c5e-fa0cb3e2ed05 + version: -1 + name: Auto Remediation + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "34" + - "27" + - "22" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 2370 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "21": + id: "21" + taskid: f4cea7e3-11aa-4d81-89fd-919f33f6f1a9 + type: regular + task: + id: f4cea7e3-11aa-4d81-89fd-919f33f6f1a9 + version: -1 + name: Okta - Clear user sessions + description: |- + Removes all active identity provider sessions. This forces the user to authenticate upon the next operation. Optionally revokes OpenID Connect and OAuth refresh and access tokens issued to the user. + For more information and examples: + https://developer.okta.com/docs/reference/api/users/#user-sessions + script: '|||okta-clear-user-sessions' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "24" + scriptarguments: + userId: + complex: + root: Account + filters: + - - operator: isEqualString + left: + value: + simple: Account.Type + iscontext: true + right: + value: + simple: Okta + ignorecase: true + accessor: ID + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 860, + "y": 2730 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: true + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "22": + id: "22" + taskid: 48e20d8a-2273-473e-8152-71ac1048deec + type: condition + task: + id: 48e20d8a-2273-473e-8152-71ac1048deec + version: -1 + name: Should Perform Cloud Remediation? + description: Whether to perform cloud remediation actions. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "24" + "yes": + - "23" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: containsString + left: + value: + complex: + root: PaloAltoNetworksXDR.Incident.alerts + accessor: tags + iscontext: true + right: + value: + simple: Azure + ignorecase: true + - - operator: isNotEmpty + left: + value: + simple: MSGraphUser.ID + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 30, + "y": 2530 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "23": + id: "23" + taskid: a21fdd8c-9e57-4a59-8bc3-5bfdce5d7a4b + type: playbook + task: + id: a21fdd8c-9e57-4a59-8bc3-5bfdce5d7a4b + version: -1 + name: Cloud Credentials Rotation - Azure + description: |- + ## **Azure Credentials Rotation Playbook** + + ### **IAM Remediation** + Protect your identity and access management: + - **Reset Password**: Resets the user password to halt any unauthorized access. + + - **Revoke Session**: Terminates current active sessions to ensure the malicious actor is locked out. + + - **Combo Action**: Resets the password and terminates all active sessions. + + ### **Service Principal Remediation** + Guard your applications: + - **Password Regeneration**: Generate a new password for the service principal, making sure the old one becomes obsolete. + playbookName: Cloud Credentials Rotation - Azure + type: playbook + iscommand: false + brand: "" + nexttasks: + '#none#': + - "24" + scriptarguments: + IAMRemediationType: + simple: ${inputs.IAMRemediationType} + identityType: + simple: IAM + userID: + simple: ${MSGraphUser.ID} + separatecontext: true + continueonerrortype: "" + loop: + iscommand: false + exitCondition: "" + wait: 1 + max: 100 + view: |- + { + "position": { + "x": 30, + "y": 2730 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: true + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "24": + id: "24" + taskid: fd48c7e6-3043-4d7f-8536-ca6b610eb4c2 + type: title + task: + id: fd48c7e6-3043-4d7f-8536-ca6b610eb4c2 + version: -1 + name: Done + description: commands.local.cmd.close.inv + type: title + iscommand: false + brand: Builtin + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 2930 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "25": + id: "25" + taskid: cbca2254-0769-443c-85e8-8b6b35eeb770 + type: title + task: + id: cbca2254-0769-443c-85e8-8b6b35eeb770 + version: -1 + name: Manual Remediation + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "24" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": -410, + "y": 2545 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "27": + id: "27" + taskid: bf0ca540-08c2-4b81-8cc8-68e83d308a0b + type: playbook + task: + id: bf0ca540-08c2-4b81-8cc8-68e83d308a0b + version: -1 + name: Block IP - Generic v3 + description: "This playbook blocks malicious IP addresses using all integrations that are enabled. The direction of the traffic that will be blocked is determined by the Cortex XSOAR user (and set by default to outgoing)\nNote the following:\n- some of those integrations require specific parameters to run, which are based on the playbook inputs. Also, certain integrations use FW rules or appended network objects.\n- Note that the appended network objects should be specified in blocking rules inside the system later on. \n\n\nSupported integrations for this playbook [Network security products such as FW/WAF/IPs/etc.]: \n\n* Check Point Firewall\n* Palo Alto Networks PAN-OS\n* Zscaler\n* FortiGate\n* Aria Packet Intelligence\n* Cisco Firepower \n* Cisco Secure Cloud Analytics\n* Cisco ASA\n* Akamai WAF\n* F5 SilverLine\n* ThreatX\n* Signal Sciences WAF\n* Sophos Firewall\n\n" + playbookName: Block IP - Generic v3 + type: playbook + iscommand: false + brand: "" + nexttasks: + '#none#': + - "24" + scriptarguments: + AutoCommit: + simple: ${inputs.FWAutoCommit} + CustomBlockRule: + simple: "True" + Folder: + simple: Shared + IP: + complex: + root: DBotScore + filters: + - - operator: isEqualString + left: + value: + simple: DBotScore.Type + iscontext: true + right: + value: + simple: IP + ignorecase: true + - - operator: isEqualString + left: + value: + simple: DBotScore.Score + iscontext: true + right: + value: + simple: "3" + ignorecase: true + accessor: Indicator + transformers: + - operator: uniq + InputEnrichment: + simple: "False" + InternalRange: + simple: ${inputs.InternalRange} + RuleDirection: + simple: outbound + RuleName: + simple: XSOAR - Block IP playbook - ${incident.id} + UserVerification: + simple: ${inputs.UserVerification} + separatecontext: true + continueonerrortype: "" + loop: + iscommand: false + exitCondition: "" + wait: 1 + max: 100 + view: |- + { + "position": { + "x": 450, + "y": 2530 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "29": + id: "29" + taskid: 63352686-7a00-4344-8fda-800c7c8e0dd2 + type: regular + task: + id: 63352686-7a00-4344-8fda-800c7c8e0dd2 + version: -1 + name: Fetch cloud alert extra data + description: Returns information about each alert ID. + script: '|||xdr-get-cloud-original-alerts' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "6" + scriptarguments: + alert_ids: + complex: + root: inputs.alert_id + filter_alert_fields: + simple: "false" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 450, + "y": 220 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "32": + id: "32" + taskid: 040a6334-1211-4a14-80b0-3630b5cc6a8a + type: playbook + task: + id: 040a6334-1211-4a14-80b0-3630b5cc6a8a + version: -1 + name: Okta - User Investigation + description: This playbook performs an investigation on a specific user, using queries and logs from Okta. + playbookName: Okta - User Investigation + type: playbook + iscommand: false + brand: "" + nexttasks: + '#none#': + - "35" + scriptarguments: + ASN: + complex: + root: IP + filters: + - - operator: isEqualString + left: + value: + simple: IP.Address + iscontext: true + right: + value: + simple: inputs.IPAddress + iscontext: true + accessor: ASN + transformers: + - operator: uniq + LoginCountry: + complex: + root: IP + filters: + - - operator: isEqualString + left: + value: + simple: IP.Address + iscontext: true + right: + value: + simple: inputs.IPAddress + iscontext: true + accessor: Geo.Country + transformers: + - operator: uniq + UserEmail: + complex: + root: Account.Email + accessor: Address + transformers: + - operator: uniq + separatecontext: true + continueonerrortype: "" + loop: + iscommand: false + exitCondition: "" + wait: 1 + max: 100 + view: |- + { + "position": { + "x": 1530, + "y": 1010 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: true + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "33": + id: "33" + taskid: 8ecccbd5-8eeb-4ca7-8c26-5dbc8b10ad8a + type: playbook + task: + id: 8ecccbd5-8eeb-4ca7-8c26-5dbc8b10ad8a + version: -1 + name: Cortex XDR - Get entity alerts by MITRE tactics + description: |- + This playbook is part of the Cortex XDR by Palo Alto Networks’ pack. This playbook searches alerts related to specific entities from Cortex XDR, on a given timeframe, based on MITRE tactics. + Note: The playbook's inputs enable manipulating the execution flow. Read the input descriptions for details. + playbookName: Cortex XDR - Get entity alerts by MITRE tactics + type: playbook + iscommand: false + brand: "" + nexttasks: + '#none#': + - "35" + scriptarguments: + EntityType: + simple: actor_effective_username + HuntCnCTechniques: + simple: "False" + HuntCollectionTechniques: + simple: "False" + HuntCredentialAccessTechniques: + simple: "False" + HuntDefenseEvasionTechniques: + simple: "False" + HuntDiscoveryTechniques: + simple: "False" + HuntExecutionTechniques: + simple: "False" + HuntImpactTechniques: + simple: "False" + HuntInitialAccessTechniques: + simple: "False" + HuntLateralMovementTechniques: + simple: "False" + HuntPersistenceTechniques: + simple: "False" + HuntPrivilegeEscalationTechniques: + simple: "False" + HuntReconnaissanceTechniques: + simple: "False" + RunAll: + simple: "True" + entityID: + complex: + root: inputs.Username + transformers: + - operator: Cut + args: + delimiter: + value: + simple: \ + fields: + value: + simple: "2" + timeRange: + simple: 1 day + separatecontext: true + continueonerrortype: "" + loop: + iscommand: false + exitCondition: "" + wait: 1 + max: 100 + view: |- + { + "position": { + "x": 1120, + "y": 1010 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "34": + id: "34" + taskid: 01943894-59fd-4c5b-8480-a37cbc91a7f5 + type: condition + task: + id: 01943894-59fd-4c5b-8480-a37cbc91a7f5 + version: -1 + name: Is Okta integration availale? + description: Returns 'yes' if integration brand is available. Otherwise returns 'no'. + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "24" + "yes": + - "21" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isEqualString + left: + value: + complex: + root: modules + filters: + - - operator: isEqualString + left: + value: + simple: modules.brand + iscontext: true + right: + value: + simple: Okta v2 + ignorecase: true + accessor: state + iscontext: true + right: + value: + simple: active + ignorecase: true + - - operator: isNotEmpty + left: + value: + complex: + root: Account + filters: + - - operator: isEqualString + left: + value: + simple: Account.Type + iscontext: true + right: + value: + simple: Okta + ignorecase: true + accessor: ID + iscontext: true + continueonerrortype: "" + view: |- + { + "position": { + "x": 860, + "y": 2530 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "35": + id: "35" + taskid: c2870a26-eb1e-4de8-8557-76cb91e5da68 + type: regular + task: + id: c2870a26-eb1e-4de8-8557-76cb91e5da68 + version: -1 + name: Set the Number of related alerts + description: |- + Set a value in context under the key you entered. If no value is entered, the script doesn't do anything. + + This automation runs using the default Limited User role, unless you explicitly change the permissions. + For more information, see the section about permissions here: + https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.12/Cortex-XSOAR-Administrator-Guide/Automations + scriptName: SetAndHandleEmpty + type: regular + iscommand: false + brand: Builtin + nexttasks: + '#none#': + - "12" + scriptarguments: + key: + simple: NumOfRelatedAlerts + value: + complex: + root: ArraySize + transformers: + - operator: SetIfEmpty + args: + applyIfEmpty: {} + defaultValue: + value: + simple: "0" + separatecontext: false + continueonerrortype: "" + view: |- + { + "position": { + "x": 1120, + "y": 1180 + } + } + note: false + timertriggers: [] + ignoreworker: false + fieldMapping: + - incidentfield: User Risk Level + output: + simple: ${PaloAltoNetworksXDR.RiskyUser.risk_level} + - incidentfield: Failed Logon Events + output: + complex: + root: AzureFailLoginCount + transformers: + - operator: append + args: + item: + value: + simple: NumOfOktaFailedLogon + iscontext: true + - incidentfield: Email + output: + simple: ${ActiveDirectory.Users.mail} + - incidentfield: Account Member Of + output: + simple: ${ActiveDirectory.Users.memberOf} + - incidentfield: Account Status + output: + simple: ${Account.Status} + - incidentfield: Cloud Account ID + output: + simple: ${MSGraphUser.ID} + - incidentfield: Account ID + output: + complex: + root: Account + filters: + - - operator: isEqualString + left: + value: + simple: Account.Type + iscontext: true + right: + value: + simple: Okta + ignorecase: true + - - operator: notContainsGeneral + left: + value: + simple: Account.ID + iscontext: true + right: + value: + simple: "=" + accessor: ID + - incidentfield: Manager Email Address + output: + simple: ${UserManagerEmail} + - incidentfield: XDR Alert Search Results + output: + simple: ${PaloAltoNetworksXDR.Alert} + - incidentfield: Alert Name + output: + simple: ${inputs.AlertName} + - incidentfield: Detected User + output: + simple: ${inputs.Username} + - incidentfield: Username + output: + simple: ${inputs.Username} + - incidentfield: Number Of Found Related Alerts + output: + simple: ${NumOfRelatedAlerts} + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false +view: |- + { + "linkLabelsPosition": { + "12_13_#default#": 0.51, + "12_16_yes": 0.33, + "13_14_Non-Malicious": 0.61, + "13_16_Malicious": 0.35, + "22_23_yes": 0.44, + "22_24_#default#": 0.33, + "2_29_yes": 0.44, + "34_24_#default#": 0.31 + }, + "paper": { + "dimensions": { + "height": 3235, + "width": 2320, + "x": -410, + "y": -240 + } + } + } +inputs: +- key: AlertName + value: {} + required: false + description: Alert name. + playbookInputQuery: +- key: alert_id + value: {} + required: false + description: Alert ID. + playbookInputQuery: +- key: IPAddress + value: {} + required: false + description: IP address from the XDR alert. + playbookInputQuery: +- key: Username + value: {} + required: false + description: User name. + playbookInputQuery: +- key: RelatedAlertsThreshold + value: + simple: "5" + required: false + description: | + This is the minimum threshold for Cortex XDR related alerts, based on MITRE tactics used to identify malicious activity by the user in the last 1 day. + playbookInputQuery: +- key: FailedLogonThreshold + value: + simple: "30" + required: false + description: |- + This is the minimum threshold for user login failures within the last 1 day. + For example: If this input is set to '30', and the 'Okta - User Investigation' or the 'Azure - User Investigation' sub-playbooks have found 31 failed login attempts - It will classify this behavior as malicious activity. + The default value is '30'. + playbookInputQuery: +- key: OktaSuspiciousActivitiesThreshold + value: + simple: "5" + required: false + description: |- + This is the minimum threshold for suspicious Okta activity events by the user in the last 1 day. + For example: If this input is set to '5', and the 'Okta - User Investigation' sub-playbooks have found 6 events of suspicious activity by the user - It will classify this behavior as malicious activity. + The default value is '5'. + playbookInputQuery: +- key: AutoRemediation + value: + simple: "False" + required: false + description: |- + Whether to execute the remediation flow automatically. + Possible values are: "True" and "False". + playbookInputQuery: +- key: IAMRemediationType + value: + simple: Revoke + required: false + description: |- + The response playbook provides the following remediation actions using MSGraph Users: + + Reset: By entering "Reset" in the input, the playbook will execute password reset. + + Revoke: By entering "Revoke" in the input, the playbook will revoke the user's session. + + ALL: By entering "ALL" in the input, the playbook will execute the reset password and revoke session tasks. + playbookInputQuery: +- key: FWAutoCommit + value: + simple: "Yes" + required: false + description: "This input determines whether to commit the configuration automatically on PAN-OS devices and other firewalls. \nYes - Commit automatically.\nNo - Commit manually." + playbookInputQuery: +- key: UserVerification + value: + simple: "False" + required: false + description: "Whether to provide user verification for blocking those IPs. \nPossible values: True/False. Default: True. \n\nFalse - No prompt will be displayed to the user.\nTrue - The server will ask the user for blocking verification and will display the blocking list." + playbookInputQuery: +- key: InternalRange + value: + complex: + root: lists + accessor: PrivateIPs + transformers: + - operator: RegexReplace + args: + action_dt: {} + ignore_case: {} + multi_line: {} + output_format: {} + period_matches_newline: {} + regex: + value: + simple: IANA_Private_Address + required: false + description: 'A list of internal IP ranges to check IP addresses against. The list should be provided in CIDR notation, separated by commas. An example of a list of ranges would be: "172.16.0.0/12,10.0.0.0/8,192.168.0.0/16" (without quotes). If a list is not provided, will use the default list provided in the IsIPInRanges script (the known IPv4 private address ranges).' + playbookInputQuery: +inputSections: +- inputs: + - AlertName + - alert_id + name: Incident Management + description: Incident management settings and data, including escalation processes, user engagements and ticketing methods. +- inputs: + - IPAddress + - Username + name: Enrichment + description: Enrichment settings and data, including assets and indicators enrichment using third-party enrichers. +- inputs: + - RelatedAlertsThreshold + - FailedLogonThreshold + - OktaSuspiciousActivitiesThreshold + name: Investigation + description: Investigation settings and data, including any deep dive incident investigation and verdict determination. +- inputs: + - AutoRemediation + - IAMRemediationType + - FWAutoCommit + - UserVerification + - InternalRange + name: Remediation + description: Remediation settings and data, including containment, eradication, and recovery. +outputSections: +- outputs: [] + name: General (Outputs group) + description: Generic group for outputs +outputs: [] +tests: +- No tests (auto formatted) +fromversion: 6.10.0 diff --git a/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Identity_Analytics_README.md b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Identity_Analytics_README.md new file mode 100644 index 000000000000..2843782af542 --- /dev/null +++ b/Packs/CortexXDR/Playbooks/playbook-Cortex_XDR_-_Identity_Analytics_README.md @@ -0,0 +1,80 @@ +The `Cortex XDR - Identity Analytics` playbook is designed to handle Cortex XDR Identity Analytics alerts and executes the following: + +Analysis: +- Enriches the IP address and the account, providing additional context and information about these indicators. + +Verdict: +- Determines the appropriate verdict based on the data collected from the enrichment phase. + +Investigation: +- Checks for related Cortex XDR alerts to the user by Mitre tactics to identify malicious activity. +- Checks for specific arguments for malicious usage from Okta using the 'Okta User Investigation' sub-playbook. +- Checks for specific arguments for malicious usage from Azure using the 'Azure User Investigation' sub-playbook. + +Verdict Handling: +- Handles malicious alerts by initiating appropriate response actions, including blocking malicious IP addresses and revoking or clearing user's sessions. +- Handles non-malicious alerts identified during the investigation. + +The playbook is used as a sub-playbook in ‘Cortex XDR Alerts Handling v2’. + + +## Dependencies + +This playbook uses the following sub-playbooks, integrations, and scripts. + +### Sub-playbooks + +* Azure - User Investigation +* Cloud Credentials Rotation - Azure +* Okta - User Investigation +* Cortex XDR - Get entity alerts by MITRE tactics +* Block IP - Generic v3 +* Cloud IAM Enrichment - Generic +* Account Enrichment - Generic v2.1 + +### Integrations + +* XDR_iocs +* CortexXDRIR +* XQLQueryingEngine + +### Scripts + +SetAndHandleEmpty + +### Commands + +* okta-clear-user-sessions +* xdr-get-cloud-original-alerts +* setIncident +* ip + +## Playbook Inputs + +--- + +| **Name** | **Description** | **Default Value** | **Required** | +| --- | --- | --- | --- | +| AlertName | Alert name. | | Optional | +| alert_id | Alert ID. | | Optional | +| IPAddress | IP address from the XDR alert. | | Optional | +| Username | User name. | | Optional | +| RelatedAlertsThreshold | This is the minimum threshold for Cortex XDR related alerts, based on MITRE tactics used to identify malicious activity by the user in the last 1 day.
    | 5 | Optional | +| FailedLogonThreshold | This is the minimum threshold for user login failures within the last 1 day.
    For example: If this input is set to '30', and the 'Okta - User Investigation' or the 'Azure - User Investigation' sub-playbooks have found 31 failed login attempts - It will classify this behavior as malicious activity.
    The default value is '30'. | 30 | Optional | +| OktaSuspiciousActivitiesThreshold | This is the minimum threshold for suspicious Okta activity events by the user in the last 1 day.
    For example: If this input is set to '5', and the 'Okta - User Investigation' sub-playbooks have found 6 events of suspicious activity by the user - It will classify this behavior as malicious activity.
    The default value is '5'. | 5 | Optional | +| AutoRemediation | Whether to execute the remediation flow automatically.
    Possible values are: "True" and "False". | False | Optional | +| IAMRemediationType | The response playbook provides the following remediation actions using MSGraph Users:

    Reset: By entering "Reset" in the input, the playbook will execute password reset.

    Revoke: By entering "Revoke" in the input, the playbook will revoke the user's session.

    ALL: By entering "ALL" in the input, the playbook will execute the reset password and revoke session tasks. | Revoke | Optional | +| FWAutoCommit | This input determines whether to commit the configuration automatically on PAN-OS devices and other FWs.
    Yes - Commit automatically.
    No - Commit manually. | Yes | Optional | +| UserVerification | Possible values: True/False. Default: True.
    Whether to provide user verification for blocking those IPs.

    False - No prompt will be displayed to the user.
    True - The server will ask the user for blocking verification and will display the blocking list. | False | Optional | +| InternalRange | A list of internal IP ranges to check IP addresses against. The list should be provided in CIDR notation, separated by commas. An example of a list of ranges would be: "172.16.0.0/12,10.0.0.0/8,192.168.0.0/16" \(without quotes\). If a list is not provided, will use the default list provided in the IsIPInRanges script \(the known IPv4 private address ranges\). | lists.PrivateIPs | Optional | + +## Playbook Outputs + +--- +There are no outputs for this playbook. + +## Playbook Image + +--- + +![Cortex XDR - Identity Analytics](../doc_files/Cortex_XDR_-_Identity_Analytics.png) diff --git a/Packs/CortexXDR/ReleaseNotes/6_1_18.md b/Packs/CortexXDR/ReleaseNotes/6_1_18.md new file mode 100644 index 000000000000..5393849fde26 --- /dev/null +++ b/Packs/CortexXDR/ReleaseNotes/6_1_18.md @@ -0,0 +1,40 @@ + +#### Layouts + +##### Cortex XDR Incident + +Added a dedicated tab for Identity Analytics alerts handling. + +#### Mappers + +##### XDR - Incoming Mapper +Added a new mapping for the incident field `alert tags`. + +#### Playbooks + +##### Cortex XDR Alerts Handling v2 +Added a flow for the new *Identity Analytics* playbook. +##### New: Cortex XDR - Identity Analytics +New: The `Cortex XDR - Identity Analytics` playbook is designed to handle Cortex XDR Identity Analytics alerts and executes the following: + +Analysis: +- Enriches the IP address and the account, providing additional context and information about these indicators. + +Verdict: +- Determines the appropriate verdict based on the data collected from the enrichment phase. + +Investigation: +- Checks for related Cortex XDR alerts to the user by Mitre tactics to identify malicious activity. +- Checks for specific arguments for malicious usage from Okta using the 'Okta User Investigation' sub-playbook. +- Checks for specific arguments for malicious usage from Azure using the 'Azure User Investigation' sub-playbook. + +Verdict Handling: +- Handles malicious alerts by initiating appropriate response actions, including blocking malicious IP addresses and revoking or clearing user's sessions. +- Handles non-malicious alerts identified during the investigation. + +The playbook is used as a sub-playbook in ‘Cortex XDR Alerts Handling v2’. + (Available from Cortex XSOAR 6.10.0). +##### Cortex XDR - First SSO Access - Set Verdict +Deprecated. Use `Cortex XDR - Identity Analytics` instead. +##### Cortex XDR - First SSO Access +Deprecated. Use `Cortex XDR - Identity Analytics` instead. diff --git a/Packs/CortexXDR/doc_files/Cortex_XDR_-_Identity_Analytics.png b/Packs/CortexXDR/doc_files/Cortex_XDR_-_Identity_Analytics.png new file mode 100644 index 0000000000000000000000000000000000000000..356af7712c968007a0a92ffaa8d11a96ff810015 GIT binary patch literal 388618 zcmeEvcRbbm|9FW+*T^iHAuFUv_KCtVqC*s+lCouIJ1vzhqwKC@hh$}I5oOCBMfOVe z{ypEP`rO04-{1H5`~LC!M`j)K=#CxiJJ6?3Y2PxO=y85xU{WZ)A@x-4dWaeg zF%j44N7ScJlW-7`-_qR4C(qk-4ka(~WuM_*?v@V%XQ=n?Y29_3sOdC{c#uA|>2AVY z{GLPHWXk+c)o481X4ksy4~uX-{uF!BZF>G3*_EG$DFTGJAjM)E!g}rxR)5!L4o%e4-{dX|@ zgmVv<3+aCY?5_i*M0%qzpLr=x6C4mbMqV=Cs{fg#!4%o9A(?1>Wq!PQSxu4PAv`)# z=yzgqdZ~9E2@s>{ip|`~bp_W{PPthL6d|0NFHq!c z=ZTcVwJ>)8!2jnwV1E_7yS$*n!O0M8LG5`iFYL z&l^;U!WtUamS;IVYGb6teL{wE3-+?lhZJ6cryAObYIp5^=PhKUuC5+jb~j|Dh-Qd$ z8^^3*Q0%F~d9`N