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

Mde fetch alerts by detectionsource #28697

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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