Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XSUP-31342 - XDR mirroring changes incident resolution #32359

Merged
merged 28 commits into from Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b34afa3
added more debug logs to the mirroring process
RotemAmit Jan 23, 2024
fa8cb73
more debug logs
RotemAmit Feb 4, 2024
17abfb1
updated the schema
RotemAmit Feb 6, 2024
fcaf2c5
added ckose_reason
RotemAmit Feb 6, 2024
68ad2e3
updated the schema name
RotemAmit Feb 7, 2024
9702919
updated the outgoing mapper and some debug logs
RotemAmit Feb 7, 2024
b6a3346
Merge branch 'master' of github.com:demisto/content into xsup-31342/x…
RotemAmit Feb 7, 2024
9c85dd7
added RN
RotemAmit Feb 7, 2024
8db4f92
Merged master into current branch.
Feb 8, 2024
c67ebfe
Bump pack from version CortexXDR to 6.1.14.
Feb 8, 2024
7b89101
Merged master into current branch.
Feb 11, 2024
83aefc2
Bump pack from version CortexXDR to 6.1.15.
Feb 11, 2024
2327325
updated test_get_mapping_fields_command
RotemAmit Feb 11, 2024
91f03a9
Merge branch 'xsup-31342/xdr_resolved_other' of github.com:demisto/co…
RotemAmit Feb 11, 2024
5d8281c
Merge branch 'master' of github.com:demisto/content into xsup-31342/x…
RotemAmit Feb 11, 2024
ef7c437
updated handle_outgoing_issue_closure to use close_reason or closeReason
RotemAmit Feb 11, 2024
d59a362
updated RN and docker image
RotemAmit Feb 11, 2024
cf13558
added a unit test test_handle_outgoing_issue_closure
RotemAmit Feb 12, 2024
8e4ae25
added RN to core pack and ctf01 pack
RotemAmit Feb 12, 2024
3ad53ef
Merge branch 'master' of github.com:demisto/content into xsup-31342/x…
RotemAmit Feb 12, 2024
dc93324
Merge branch 'master' of github.com:demisto/content into xsup-31342/x…
RotemAmit Feb 13, 2024
ab98562
Merged master into current branch.
Feb 13, 2024
ec660a0
Bump pack from version CortexXDR to 6.1.16.
Feb 13, 2024
1d0aed9
updated the RN
RotemAmit Feb 13, 2024
c53500a
fixed conflicts
RotemAmit Feb 13, 2024
94a426f
Merge branch 'xsup-31342/xdr_resolved_other' of github.com:demisto/co…
RotemAmit Feb 13, 2024
ebe4306
added an incident type to the outgoing mapper and updated the RN
RotemAmit Feb 14, 2024
5149883
Merge branch 'master' of github.com:demisto/content into xsup-31342/x…
RotemAmit Feb 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 8 additions & 3 deletions Packs/ApiModules/Scripts/CoreIRApiModule/CoreIRApiModule.py
Expand Up @@ -2856,18 +2856,23 @@ def handle_user_unassignment(update_args):


def handle_outgoing_issue_closure(remote_args):
incident_id = remote_args.remote_incident_id
demisto.debug(f"handle_outgoing_issue_closure {incident_id=}")
update_args = remote_args.delta
current_remote_status = remote_args.data.get('status') if remote_args.data else None
close_reason = update_args.get('close_reason') or update_args.get('closeReason')
demisto.debug(f'{current_remote_status=} {remote_args.data=} {remote_args.inc_status=} {close_reason=}')
# force closing remote incident only if:
# The XSOAR incident is closed
# and the remote incident isn't already closed
if remote_args.inc_status == 2 and \
current_remote_status not in XDR_RESOLVED_STATUS_TO_XSOAR:
current_remote_status not in XDR_RESOLVED_STATUS_TO_XSOAR and close_reason:

if close_notes := update_args.get('closeNotes'):
demisto.debug(f"handle_outgoing_issue_closure {incident_id=} {close_notes=}")
update_args['resolve_comment'] = close_notes
update_args['status'] = XSOAR_RESOLVED_STATUS_TO_XDR.get(update_args.get('closeReason', 'Other'))
demisto.debug(f"Closing Remote incident with status {update_args['status']}")
update_args['status'] = XSOAR_RESOLVED_STATUS_TO_XDR.get(close_reason, 'Other')
demisto.debug(f"handle_outgoing_issue_closure Closing Remote incident {incident_id=} with status {update_args['status']}")


def get_update_args(remote_args):
Expand Down
Expand Up @@ -9,7 +9,7 @@

import demistomock as demisto
from CommonServerPython import Common, tableToMarkdown, pascalToSpace, DemistoException
from CoreIRApiModule import CoreClient
from CoreIRApiModule import CoreClient, handle_outgoing_issue_closure
from CoreIRApiModule import add_tag_to_endpoints_command, remove_tag_from_endpoints_command, quarantine_files_command, \
isolate_endpoint_command, list_user_groups_command, parse_user_groups, list_users_command, list_roles_command, \
change_user_role_command, list_risky_users_or_host_command, enrich_error_message_id_group_role, get_incidents_command
Expand Down Expand Up @@ -3789,3 +3789,37 @@ def test_get_starred_incident_list(self, requests_mock):
_, outputs, _ = get_incidents_command(client, args)

assert outputs['CoreApiModule.Incident(val.incident_id==obj.incident_id)'][0]['starred'] is True


INPUT_test_handle_outgoing_issue_closure = load_test_data('./test_data/handle_outgoing_issue_closure_input.json')


@pytest.mark.parametrize("args, expected_delta",
[
# close an incident from xsoar ui, and the incident type isn't cortex xdr incident
(INPUT_test_handle_outgoing_issue_closure["xsoar_ui_common_mapping"]["args"],
INPUT_test_handle_outgoing_issue_closure["xsoar_ui_common_mapping"]["expected_delta"]),
# close an incident from xsoar ui, and the incident type is cortex xdr incident
(INPUT_test_handle_outgoing_issue_closure["xsoar_ui_cortex_xdr_incident"]["args"],
INPUT_test_handle_outgoing_issue_closure["xsoar_ui_cortex_xdr_incident"]["expected_delta"]),
# close an incident from XDR
(INPUT_test_handle_outgoing_issue_closure["xdr"]["args"],
INPUT_test_handle_outgoing_issue_closure["xdr"]["expected_delta"])
])
def test_handle_outgoing_issue_closure(args, expected_delta):
"""
Given: An UpdateRemoteSystemArgs object.
- case A: data & delta that match a case of closing an incident from xsoar ui, and the incident type isn't cortex xdr incident
- case B: data & delta that match a case of closing an incident from xsoar ui, and the incident type is cortex xdr incident
- case C: data & delta that match a case of closing an incident from XDR.
When: Closing an incident.
Then: Ensure the update_args has the expected value.
- case A: a status is added with the correct value.
- case B: a status is added with the correct value.
- case C: a status isn't added. (If the closing status came from XDR, there is no need to update it again)
"""
from CommonServerPython import UpdateRemoteSystemArgs

remote_args = UpdateRemoteSystemArgs(args)
handle_outgoing_issue_closure(remote_args)
assert remote_args.delta == expected_delta
@@ -0,0 +1,69 @@
{
"xsoar_ui_common_mapping": {
"args": {
"remoteId": "47",
"delta": {
"close_reason": "False Positive",
"resolve_comment": "closing 47 false positive"
},
"data": {
"assigned_user_mail": "assigned_user_mail",
"assigned_user_pretty_name": "User",
"close_reason": "False Positive",
"manual_severity": "high",
"resolve_comment": "closing 47 false positive",
"status": "new"
},
"status": 2
},
"expected_delta": {
"close_reason": "False Positive",
"resolve_comment": "closing 47 false positive",
"status": "resolved_false_positive"
}
},
"xsoar_ui_cortex_xdr_incident": {
"args": {
"remoteId": "47",
"delta": {
"closeReason": "False Positive",
"closeNotes": "closing 47 false positive"
},
"data": {
"assigned_user_mail": "assigned_user_mail",
"assigned_user_pretty_name": "User",
"manual_severity": "high",
"status": "new"
},
"status": 2
},
"expected_delta": {
"closeReason": "False Positive",
"closeNotes": "closing 47 false positive",
"resolve_comment": "closing 47 false positive",
"status": "resolved_false_positive"
}
},
"xdr": {
"args": {
"remoteId": "47",
"delta": {
"close_reason": "False Positive",
"resolve_comment": "resolving from xdr"
},
"data": {
"assigned_user_mail": "assigned_user_mail",
"assigned_user_pretty_name": "User",
"close_reason": "False Positive",
"manual_severity": "high",
"resolve_comment": "resolving from xdr",
"status": "resolved_false_positive"
},
"status": 2
},
"expected_delta": {
"close_reason": "False Positive",
"resolve_comment": "resolving from xdr"
}
}
}
5 changes: 5 additions & 0 deletions Packs/Core/ReleaseNotes/3_0_19.md
@@ -0,0 +1,5 @@

#### Integrations

##### Investigation & Response
- Updated the outgoing mirroring process to also check the **close reason** of the incident, if needed.
2 changes: 1 addition & 1 deletion Packs/Core/pack_metadata.json
Expand Up @@ -2,7 +2,7 @@
"name": "Core - Investigation and Response",
"description": "Automates incident response",
"support": "xsoar",
"currentVersion": "3.0.18",
"currentVersion": "3.0.19",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
Expand Up @@ -127,12 +127,29 @@
}
}
},
"Malware Investigation and Response": {
"dontMapEventToLabels": false,
"internalMapping": {
"close_reason": {
"simple": "closeReason"
},
"resolve_comment": {
"simple": "closeNotes"
},
"status": {
"simple": "externalstatus.[0]"
}
}
},
"dbot_classification_incident_type_all": {
"dontMapEventToLabels": false,
"internalMapping": {
"assigned_user_mail": {
"simple": "xdrassigneduseremail"
},
"close_reason": {
"simple": "closeReason"
},
"manual_severity": {
"complex": {
"filters": [],
Expand Down Expand Up @@ -207,6 +224,9 @@
},
"resolve_comment": {
"simple": "closeNotes"
},
"status": {
"simple": "xdrstatusv2"
}
}
}
Expand Down
17 changes: 15 additions & 2 deletions Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR.py
Expand Up @@ -15,7 +15,7 @@
API_KEY_LENGTH = 128

INTEGRATION_CONTEXT_BRAND = 'PaloAltoNetworksXDR'
XDR_INCIDENT_TYPE_NAME = 'Cortex XDR Incident'
XDR_INCIDENT_TYPE_NAME = 'Cortex XDR Incident Schema'
INTEGRATION_NAME = 'Cortex XDR - IR'

XDR_INCIDENT_FIELDS = {
Expand All @@ -33,6 +33,8 @@
"manual_severity": {"description": "Incident severity assigned by the user. "
"This does not affect the calculated severity low medium high",
"xsoar_field_name": "severity"},
"close_reason": {"description": "The close reason of the XSOAR incident",
"xsoar_field_name": "closeReason"}
}

MIRROR_DIRECTION = {
Expand Down Expand Up @@ -420,6 +422,7 @@ def get_incident_extra_data_command(client, args):

incident = raw_incident.get('incident')
incident_id = incident.get('incident_id')
demisto.debug(f"in get_incident_extra_data_command {incident_id=} {incident=}")
raw_alerts = raw_incident.get('alerts').get('data')
context_alerts = clear_trailing_whitespace(raw_alerts)
for alert in context_alerts:
Expand Down Expand Up @@ -624,9 +627,12 @@ def handle_incoming_user_unassignment(incident_data):


def handle_incoming_closing_incident(incident_data):
incident_id = incident_data.get('incident_id')
demisto.debug(f'handle_incoming_closing_incident {incident_data=} {incident_id=}')
closing_entry = {} # type: Dict
if incident_data.get('status') in XDR_RESOLVED_STATUS_TO_XSOAR:
demisto.debug(f"Closing XDR issue {incident_data.get('incident_id')}")
demisto.debug(f"handle_incoming_closing_incident {incident_data.get('status')=} {incident_id=}")
demisto.debug(f"Closing XDR issue {incident_id=}")
closing_entry = {
'Type': EntryType.NOTE,
'Contents': {
Expand All @@ -638,11 +644,14 @@ def handle_incoming_closing_incident(incident_data):
}
incident_data['closeReason'] = closing_entry['Contents']['closeReason']
incident_data['closeNotes'] = closing_entry['Contents']['closeNotes']
demisto.debug(f"handle_incoming_closing_incident {incident_id=} {incident_data['closeReason']=} "
f"{incident_data['closeNotes']=}")

if incident_data.get('status') == 'resolved_known_issue':
close_notes = f'Known Issue.\n{incident_data.get("closeNotes", "")}'
closing_entry['Contents']['closeNotes'] = close_notes
incident_data['closeNotes'] = close_notes
demisto.debug(f"handle_incoming_closing_incident {incident_id=} {close_notes=}")

return closing_entry

Expand Down Expand Up @@ -765,12 +774,16 @@ def get_remote_data_command(client, args):

def update_remote_system_command(client, args):
remote_args = UpdateRemoteSystemArgs(args)
incident_id = remote_args.remote_incident_id
demisto.debug(f"update_remote_system_command {incident_id=} {remote_args=}")

if remote_args.delta:
demisto.debug(f'Got the following delta keys {str(list(remote_args.delta.keys()))} to update'
f'incident {remote_args.remote_incident_id}')
demisto.debug(f'{remote_args.delta=}')
try:
if remote_args.incident_changed:
demisto.debug(f"update_remote_system_command {incident_id=} {remote_args.incident_changed=}")
update_args = get_update_args(remote_args)

update_args['incident_id'] = remote_args.remote_incident_id
Expand Down
2 changes: 1 addition & 1 deletion Packs/CortexXDR/Integrations/CortexXDRIR/CortexXDRIR.yml
Expand Up @@ -3471,7 +3471,7 @@ script:
isArray: true
name: xdr-remove-user-role
description: Remove one or more users from a role.
dockerimage: demisto/python3:3.10.13.86272
dockerimage: demisto/python3:3.10.13.87159
isfetch: true
isfetch:xpanse: false
script: ''
Expand Down
Expand Up @@ -435,7 +435,7 @@ def test_get_mapping_fields_command():
- the result fits the expected mapping.
"""
from CortexXDRIR import get_mapping_fields_command
expected_mapping = {"Cortex XDR Incident": {
expected_mapping = {"Cortex XDR Incident Schema": {
"status": "Current status of the incident: \"new\",\"under_"
"investigation\",\"resolved_known_issue\","
"\"resolved_duplicate\",\"resolved_false_positive\","
Expand All @@ -444,7 +444,8 @@ def test_get_mapping_fields_command():
"assigned_user_pretty_name": "Full name of the user assigned to the incident.",
"resolve_comment": "Comments entered by the user when the incident was resolved.",
"manual_severity": "Incident severity assigned by the user. This does not "
"affect the calculated severity low medium high"
"affect the calculated severity low medium high",
"close_reason": "The close reason of the XSOAR incident"
}}
res = get_mapping_fields_command()
assert expected_mapping == res.extract_mapping()
Expand Down
14 changes: 14 additions & 0 deletions Packs/CortexXDR/ReleaseNotes/6_1_16.md
@@ -0,0 +1,14 @@

#### Integrations

##### Palo Alto Networks Cortex XDR - Investigation and Response
- Updated the outgoing mirroring process to also check the **close reason** of the incident, if needed.
- Updated the name of the schema to Cortex XDR Incident Schema.
- Updated the Docker image to: *demisto/python3:3.10.13.87159*.

#### Mappers

##### Cortex XDR - Outgoing Mapper
- Added the field close_reason to the mapper.
- Added the field status to the Common Mapping.
- Added the incident type **Malware Investigation and Response** to the outgoing mapper.
2 changes: 1 addition & 1 deletion Packs/CortexXDR/pack_metadata.json
Expand Up @@ -2,7 +2,7 @@
"name": "Cortex XDR by Palo Alto Networks",
"description": "Automates Cortex XDR incident response, and includes custom Cortex XDR incident views and layouts to aid analyst investigations.",
"support": "xsoar",
"currentVersion": "6.1.15",
"currentVersion": "6.1.16",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
6 changes: 6 additions & 0 deletions Packs/ctf01/ReleaseNotes/1_0_7.md
@@ -0,0 +1,6 @@

#### Integrations

##### Cortex XDR - IR CTF

- Updated the outgoing mirroring process to also check the **close reason** of the incident, if needed.
2 changes: 1 addition & 1 deletion Packs/ctf01/pack_metadata.json
Expand Up @@ -2,7 +2,7 @@
"name": "Capture The Flag - 01",
"description": "XSOAR's Capture the flag (CTF)",
"support": "xsoar",
"currentVersion": "1.0.6",
"currentVersion": "1.0.7",
"serverMinVersion": "8.2.0",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
Expand Down