Skip to content

Commit

Permalink
Mde fetch alerts by detectionsource (demisto#28697)
Browse files Browse the repository at this point in the history
* Mde fetch alerts by detectionsource (demisto#28384)

* init filter changes

* release notes

* adjust readme

* dockerimage

* fixed the available detection sources
---------

Co-authored-by: ckaadic <48683125+ckaadic@users.noreply.github.com>
Co-authored-by: anas-yousef <44998563+anas-yousef@users.noreply.github.com>
  • Loading branch information
3 people authored and xsoar-bot committed Oct 5, 2023
1 parent ac5f697 commit 85828be
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,19 @@
"Unknown": None,
}

DETECTION_SOURCE_TO_API_VALUE = { # https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/alerts-queue
"Third-party sensors": "ThirdPartySensors",
"Antivirus": "WindowsDefenderAv",
"Automated investigation": "AutomatedInvestigation",
"Custom detection": "CustomDetection",
"Custom TI": "CustomerTI",
"EDR": "WindowsDefenderAtp",
"Microsoft 365 Defender": "MTP",
"Microsoft Defender for Office 365": "OfficeATP",
"Microsoft Defender Experts": "ThreatExperts",
"SmartScreen": "WindowsDefenderSmartScreen",
}

INTEGRATION_NAME = 'Microsoft Defender ATP'


Expand Down Expand Up @@ -1103,7 +1116,9 @@ class MsClient:
def __init__(self, tenant_id, auth_id, enc_key, app_name, base_url, verify, proxy, self_deployed,
alert_severities_to_fetch, alert_status_to_fetch, alert_time_to_fetch, max_fetch,
auth_type, endpoint_type, redirect_uri, auth_code, certificate_thumbprint: str | None = None,
private_key: str | None = None, managed_identities_client_id: str | None = None):
private_key: str | None = None, managed_identities_client_id: str | None = None,
alert_detectionsource_to_fetch: str | None = None):

self.endpoint_type = endpoint_type
if auth_type == 'Authorization Code':
token_retrieval_url = urljoin(MICROSOFT_DEFENDER_FOR_ENDPOINT_TOKEN_RETRIVAL_ENDPOINTS.get(endpoint_type),
Expand Down Expand Up @@ -1137,6 +1152,7 @@ def __init__(self, tenant_id, auth_id, enc_key, app_name, base_url, verify, prox
command_prefix="microsoft-atp"
)
self.ms_client = MicrosoftClient(**client_args)
self.alert_detectionsource_to_fetch = alert_detectionsource_to_fetch
self.alert_severities_to_fetch = alert_severities_to_fetch
self.alert_status_to_fetch = alert_status_to_fetch
self.alert_time_to_fetch = alert_time_to_fetch
Expand Down Expand Up @@ -3635,6 +3651,12 @@ def fetch_incidents(client: MsClient, last_run, fetch_evidence):

def _get_incidents_query_params(client, fetch_evidence, last_fetch_time):
filter_query = f'alertCreationTime+gt+{last_fetch_time}'
if client.alert_detectionsource_to_fetch:
sources = argToList(client.alert_detectionsource_to_fetch)
source_filter_list = [f"detectionSource+eq+'{DETECTION_SOURCE_TO_API_VALUE[source]}'" for source in sources]
if len(source_filter_list) > 1:
source_filter_list = list(map(lambda x: f"({x})", source_filter_list))
filter_query = filter_query + " and (" + " or ".join(source_filter_list) + ")"
if client.alert_status_to_fetch:
statuses = argToList(client.alert_status_to_fetch)
status_filter_list = [f"status+eq+'{status}'" for status in statuses]
Expand Down Expand Up @@ -5462,6 +5484,7 @@ def main(): # pragma: no cover
self_deployed: bool = params.get('self_deployed', False)
certificate_thumbprint = params.get('creds_certificate', {}).get('identifier') or params.get('certificate_thumbprint')
private_key = replace_spaces_in_credential(params.get('creds_certificate', {}).get('password')) or params.get('private_key')
alert_detectionsource_to_fetch = params.get("fetch_detectionsource")
alert_severities_to_fetch = params.get('fetch_severity')
alert_status_to_fetch = params.get('fetch_status')
alert_time_to_fetch = params.get('first_fetch_timestamp', '3 days')
Expand Down Expand Up @@ -5507,7 +5530,8 @@ def main(): # pragma: no cover
max_fetch=max_alert_to_fetch, certificate_thumbprint=certificate_thumbprint, private_key=private_key,
auth_type=auth_type, endpoint_type=endpoint_type,
auth_code=auth_code, redirect_uri=redirect_uri,
managed_identities_client_id=managed_identities_client_id
managed_identities_client_id=managed_identities_client_id,
alert_detectionsource_to_fetch=alert_detectionsource_to_fetch
)
if command == 'test-module':
if auth_type == 'Authorization Code':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,23 @@ configuration:
section: Collect
advanced: true
required: false
- display: 'DetectionSource to filter out alerts for fetching as incidents.'
name: fetch_detectionsource
options:
- Antivirus
- Automated investigation
- Custom detection
- Custom TI
- EDR
- Microsoft 365 Defender
- Microsoft Defender for Office 365
- Microsoft Defender Experts
- SmartScreen
- Third-party sensors
type: 16
section: Collect
advanced: true
required: false
- defaultvalue: Informational,Low,Medium,High
display: 'Severity to filter out alerts for fetching as incidents. Comma-separated lists are supported, e.g., Medium,High.'
name: fetch_severity
Expand Down Expand Up @@ -5492,7 +5509,7 @@ script:
execution: false
name: microsoft-atp-auth-reset
arguments: []
dockerimage: demisto/crypto:1.0.0.66562
dockerimage: demisto/crypto:1.0.0.67448
isfetch: true
runonce: false
script: '-'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def mock_demisto(mocker):
tenant_id="tenant_id", auth_id="auth_id", enc_key='enc_key', app_name='app_name', base_url='url', verify='use_ssl',
proxy='proxy', self_deployed='self_deployed', alert_severities_to_fetch='Informational,Low,Medium,High',
alert_time_to_fetch='3 days', alert_status_to_fetch='New', max_fetch='10', auth_code='', auth_type='',
redirect_uri='', endpoint_type='com')
redirect_uri='', endpoint_type='com', alert_detectionsource_to_fetch='')


def atp_mocker(mocker, file_name):
Expand Down Expand Up @@ -1272,7 +1272,7 @@ def raise_mock(params=None, overwrite_rate_limit_retry=True):

QUERY_BUILDING_CASES = [
(
'New, Resolved', 'Informational,Low,Medium,High', '5', False, '2022-02-17T14:39:01.391001Z',
'New, Resolved', 'Informational,Low,Medium,High', '5', False, '2022-02-17T14:39:01.391001Z', None,
{
'$filter': "alertCreationTime+gt+2022-02-17T14:39:01.391001Z and "
"((status+eq+'New') or (status+eq+'Resolved')) and "
Expand All @@ -1282,7 +1282,7 @@ def raise_mock(params=None, overwrite_rate_limit_retry=True):
}
),
(
None, 'Informational,Low,Medium,High', '5', False, '2022-02-17T14:39:01.391001Z',
None, 'Informational,Low,Medium,High', '5', False, '2022-02-17T14:39:01.391001Z', None,
{
'$filter': "alertCreationTime+gt+2022-02-17T14:39:01.391001Z and "
"((severity+eq+'Informational') or (severity+eq+'Low') "
Expand All @@ -1291,52 +1291,88 @@ def raise_mock(params=None, overwrite_rate_limit_retry=True):
}
),
(
'New', None, '5', False, '2022-02-17T14:39:01.391001Z',
'New', None, '5', False, '2022-02-17T14:39:01.391001Z', None,
{
'$filter': "alertCreationTime+gt+2022-02-17T14:39:01.391001Z and (status+eq+'New')",
'$orderby': 'alertCreationTime asc', '$top': '5'
}
),
(
None, 'Informational', '5', False, '2022-02-17T14:39:01.391001Z',
None, 'Informational', '5', False, '2022-02-17T14:39:01.391001Z', None,
{
'$filter': "alertCreationTime+gt+2022-02-17T14:39:01.391001Z and (severity+eq+'Informational')",
'$orderby': 'alertCreationTime asc', '$top': '5'
}
),
(
None, None, '5', False, '2022-02-17T14:39:01.391001Z',
None, None, '5', False, '2022-02-17T14:39:01.391001Z', None,
{
'$filter': 'alertCreationTime+gt+2022-02-17T14:39:01.391001Z', '$orderby': 'alertCreationTime asc',
'$top': '5'
}
),
(
'Resolved', 'High', '5', True, '2022-02-17T14:39:01.391001Z',
'Resolved', 'High', '5', True, '2022-02-17T14:39:01.391001Z', None,
{
'$filter': "alertCreationTime+gt+2022-02-17T14:39:01.391001Z and "
"(status+eq+'Resolved') and (severity+eq+'High')",
'$orderby': 'alertCreationTime asc', '$expand': 'evidence', '$top': '5'
}
),
(
None, None, '5', True, '2022-02-17T14:39:01.391001Z',
None, None, '5', True, '2022-02-17T14:39:01.391001Z', None,
{
'$filter': 'alertCreationTime+gt+2022-02-17T14:39:01.391001Z', '$orderby': 'alertCreationTime asc',
'$expand': 'evidence', '$top': '5'
}
),
(
None, None, '5', True, '2022-02-17T14:39:01.391001Z', None,
{
'$filter': 'alertCreationTime+gt+2022-02-17T14:39:01.391001Z', '$orderby': 'alertCreationTime asc',
'$expand': 'evidence', '$top': '5'
}
),
(
None, 'Informational', '5', False, '2022-02-17T14:39:01.391001Z', 'Microsoft Defender for Office 365',
{
'$filter': "alertCreationTime+gt+2022-02-17T14:39:01.391001Z and "
"(detectionSource+eq+'OfficeATP') and (severity+eq+'Informational')",
'$orderby': 'alertCreationTime asc', '$top': '5'
}
),
(
'New', None, '5', False, '2022-02-17T14:39:01.391001Z', 'EDR',
{
'$filter': "alertCreationTime+gt+2022-02-17T14:39:01.391001Z and (detectionSource+eq+'WindowsDefenderAtp') and "
"(status+eq+'New')",
'$orderby': 'alertCreationTime asc', '$top': '5'
}
),
(
'New, Resolved', 'Informational,Low,Medium,High', '5', False, '2022-02-17T14:39:01.391001Z', 'Custom detection,Custom TI',
{
'$filter': "alertCreationTime+gt+2022-02-17T14:39:01.391001Z and "
"((detectionSource+eq+'CustomDetection') or (detectionSource+eq+'CustomerTI')) and "
"((status+eq+'New') or (status+eq+'Resolved')) and "
"((severity+eq+'Informational') or (severity+eq+'Low') or (severity+eq+'Medium') "
"or (severity+eq+'High'))",
'$orderby': 'alertCreationTime asc', '$top': '5'
}
)

]


@pytest.mark.parametrize('status, severity, limit, evidence, last_fetch_time, expected_result', QUERY_BUILDING_CASES)
def test_get_incidents_query_params(status, severity, limit, evidence, last_fetch_time, expected_result):
@pytest.mark.parametrize('status, severity, limit, evidence, last_fetch_time, detection_sources, expected_result',
QUERY_BUILDING_CASES)
def test_get_incidents_query_params(status, severity, limit, evidence, last_fetch_time, expected_result, detection_sources):
from copy import deepcopy
from MicrosoftDefenderAdvancedThreatProtection import _get_incidents_query_params

client = deepcopy(client_mocker)
client.max_alerts_to_fetch = limit
client.alert_detectionsource_to_fetch = detection_sources
client.alert_severities_to_fetch = severity
client.alert_status_to_fetch = status

Expand Down Expand Up @@ -2336,7 +2372,7 @@ def test_gcc_resource(mocker, endpoint_type):
verify='use_ssl',
proxy='proxy', self_deployed='self_deployed', alert_severities_to_fetch='Informational,Low,Medium,High',
alert_time_to_fetch='3 days', alert_status_to_fetch='New', max_fetch='10', endpoint_type=endpoint_type,
auth_type='', auth_code='', redirect_uri='')
auth_type='', auth_code='', redirect_uri='', alert_detectionsource_to_fetch='')
# use requests_mock to catch a get to example.com
req = mocker.patch.object(client.ms_client, 'http_request')
with requests_mock.Mocker() as m:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Please add the following permissions to the app registration. Choose application
| Authorization code | for user-auth mode - received from the authorization step. see Detailed Instructions section | False |
| Azure Managed Identities Client ID | The Managed Identities client ID for authentication - relevant only if the integration is running on Azure VM. | UUID |
| Status to filter out alerts for fetching as incidents | The property values are, "New", "InProgress" or "Resolved". Comma-separated lists are supported, e.g., New,Resolved. | New,In Progress,Resolved |
| DetecitonSource to filter out alters for fetching as incidents. | The property values are, "Antivirus", "CustomDetection", "CustomTI", "EDR" and "MDO". Comma-separated lists are supported, e.g., Antivirus,EDR. | CustomDetection,EDR |
| Severity to filter out alerts for fetching as incidents | The property values are, "Informational", "Low", "Medium" and "High". Comma-separated lists are supported, e.g., Medium,High. | Medium,High |
| Maximum number of incidents to fetch | The maximum number of incidents to retrieve per fetch. | 50 |
| Trust any Certificate (Not Secure) | When selected, certificates are not checked. | N/A |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#### Integrations

##### Microsoft Defender for Endpoint

- Updated the Docker image to: **demisto/crypto:1.0.0.67448**.
- Added the fetch_detectionsource parameter to filter the results of fetch-incidents by DetectionSource.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"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.15.35",
"currentVersion": "1.16.0",

"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down

0 comments on commit 85828be

Please sign in to comment.