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

Microsoft support of national clouds - Microsoft Defender for Cloud Apps #27705

Merged
merged 45 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
780116f
CIAC-3854 [Email Communication] Add "Create_Incidents" parameter and …
May 16, 2023
dd902f0
gcc support
May 28, 2023
c9ad31d
gcc support
May 28, 2023
738c9fd
fix ruff
Jun 5, 2023
352beac
fix ruff
Jun 5, 2023
81e2473
Apply suggestions from code review
kobymeir Jun 14, 2023
fc2311e
Nightly build XSIAM - search & install packs retry mechanism is broken.
Jun 14, 2023
48449c1
mcas - ut and code convention
Jun 7, 2023
c9cac2c
CIAC-6390 Microsoft Defender for Applications (MCAS/MDA)
Jun 14, 2023
e96f18b
CIAC-6390 Microsoft Defender for Applications (MCAS/MDA)
Jun 14, 2023
d22f49e
mcas
Jun 19, 2023
d529687
lint fixes
Jun 26, 2023
b446e19
adding azure cloud
Jun 26, 2023
3222fce
Merge branch 'master' into microsoft-usgov-support-mcas
kobymeir Jun 26, 2023
f9b737c
adding azure cloud
Jun 26, 2023
9056db6
sourcery
Jun 26, 2023
89c4286
sourcery
Jun 26, 2023
b9ac83e
sourcery
Jun 26, 2023
b1408d4
sourcery
Jun 26, 2023
443309d
sourcery
Jun 26, 2023
7ced59a
pr review
Jul 6, 2023
8c29c0c
pr review
Jul 6, 2023
0f04d95
Merge branch 'master' into microsoft-usgov-support-mcas
kobymeir Jul 6, 2023
118d39e
pr review
Jul 6, 2023
8cddd36
Merge branch 'master' into microsoft-usgov-support-mcas
kobymeir Aug 7, 2023
2a8d855
merge conflicts
Aug 7, 2023
8e0345b
merge conflicts
Aug 7, 2023
5a9a47c
Merge branch 'master' into microsoft-usgov-support-mcas
kobymeir Aug 7, 2023
53b5be5
doc review
Aug 7, 2023
36638ca
Adding support for Microsoft Defender for APi Endpoints in the Micros…
Aug 8, 2023
1d312ea
Merge branch 'master' into microsoft-usgov-support-mcas
kobymeir Aug 8, 2023
c5f539f
Adding support for Microsoft Defender for APi Endpoints in the Micros…
Aug 8, 2023
7eb3c56
fix to api module
Aug 8, 2023
336294f
Added support for Microsoft Defender for Application Endpoints in the…
Aug 8, 2023
d923f8d
Added support for Microsoft Defender for Application Endpoints in the…
Aug 8, 2023
c0dbafd
Added support for Microsoft Defender for Application Endpoints in the…
Aug 8, 2023
39204a3
Merge branch 'master' into microsoft-usgov-support-mcas
kobymeir Aug 8, 2023
557b649
fixing UT
Aug 8, 2023
1e07878
fixing TPB
Aug 8, 2023
623597f
fixing code review issues
Aug 8, 2023
2e57111
fixing code review issues
Aug 8, 2023
3fce5b1
fixing RN issue
Aug 9, 2023
f748434
Merge branch 'master' into microsoft-usgov-support-mcas
kobymeir Aug 9, 2023
e25f29b
Merged master into current branch.
Aug 9, 2023
b0c2c50
Bump pack from version MicrosoftGraphSecurity to 2.1.27.
Aug 9, 2023
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
80 changes: 53 additions & 27 deletions Packs/ApiModules/Scripts/MicrosoftApiModule/MicrosoftApiModule.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class Resources:
MICROSOFT_DEFENDER_FOR_ENDPOINT_TYPE_CUSTOM = "Custom"
MICROSOFT_DEFENDER_FOR_ENDPOINT_DEFAULT_ENDPOINT_TYPE = "com"


# https://learn.microsoft.com/en-us/microsoft-365/security/defender/api-supported?view=o365-worldwide#endpoint-uris
# https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/gov?view=o365-worldwide#api
MICROSOFT_DEFENDER_FOR_ENDPOINT_API = {
Expand Down Expand Up @@ -124,6 +125,25 @@ class Resources:
'dod': 'https://securitycenter.onmicrosoft.us',
}

MICROSOFT_DEFENDER_FOR_APPLICATION_API = {
"com": "https://api.securitycenter.microsoft.com",
"gcc": "https://api-gcc.securitycenter.microsoft.us",
"gcc-high": "https://api-gcc.securitycenter.microsoft.us",
}


MICROSOFT_DEFENDER_FOR_APPLICATION_TYPE = {
"Worldwide": "com",
"US GCC": "gcc",
"US GCC-High": "gcc-high",
}

MICROSOFT_DEFENDER_FOR_APPLICATION_TOKEN_RETRIEVAL_ENDPOINTS = {
'com': 'https://login.microsoftonline.com',
'gcc': 'https://login.microsoftonline.us',
'gcc-high': 'https://login.microsoftonline.us',
}

# Azure Managed Identities
MANAGED_IDENTITIES_TOKEN_URL = 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01'
MANAGED_IDENTITIES_SYSTEM_ASSIGNED = 'SYSTEM_ASSIGNED'
Expand Down Expand Up @@ -568,12 +588,11 @@ def microsoft_defender_for_endpoint_get_base_url(endpoint_type, url, is_gcc=None
if is_gcc: # Backward compatible.
endpoint_type = "US GCC"
log_message_append = f" ,Overriding endpoint to {endpoint_type}, backward compatible."
elif endpoint_type == MICROSOFT_DEFENDER_FOR_ENDPOINT_TYPE_CUSTOM or not endpoint_type:
elif (endpoint_type == MICROSOFT_DEFENDER_FOR_ENDPOINT_TYPE_CUSTOM or not endpoint_type) and not url:
# When the integration was configured before our Azure Cloud support, the value will be None.
if not url:
if endpoint_type == MICROSOFT_DEFENDER_FOR_ENDPOINT_TYPE_CUSTOM:
raise DemistoException("Endpoint type is set to 'Custom' but no URL was provided.")
raise DemistoException("'Endpoint Type' is not set and no URL was provided.")
if endpoint_type == MICROSOFT_DEFENDER_FOR_ENDPOINT_TYPE_CUSTOM:
raise DemistoException("Endpoint type is set to 'Custom' but no URL was provided.")
raise DemistoException("'Endpoint Type' is not set and no URL was provided.")
endpoint_type = MICROSOFT_DEFENDER_FOR_ENDPOINT_TYPE.get(endpoint_type, 'com')
url = url or MICROSOFT_DEFENDER_FOR_ENDPOINT_API[endpoint_type]
demisto.info(f"Using url:{url}, endpoint type:{endpoint_type}{log_message_append}")
Expand All @@ -596,7 +615,7 @@ def get_azure_cloud(params, integration_name):
})

# There is no need for backward compatibility support, as the integration didn't support it to begin with.
return AZURE_CLOUDS.get(azure_cloud_arg, AZURE_WORLDWIDE_CLOUD)
return AZURE_CLOUDS.get(AZURE_CLOUD_NAME_MAPPING.get(azure_cloud_arg), AZURE_WORLDWIDE_CLOUD) # type: ignore[arg-type]


class MicrosoftClient(BaseClient):
Expand Down Expand Up @@ -720,7 +739,8 @@ def __init__(self, tenant_id: str = '',
self.managed_identities_client_id = managed_identities_client_id
self.managed_identities_resource_uri = managed_identities_resource_uri

def is_command_executed_from_integration(self):
@staticmethod
def is_command_executed_from_integration():
ctx = demisto.callingContext.get('context', {})
executed_commands = ctx.get('ExecutedCommands', [{'moduleBrand': 'Scripts'}])

Expand Down Expand Up @@ -756,7 +776,7 @@ def http_request(
}

if headers:
default_headers.update(headers)
default_headers |= headers

if self.timeout:
kwargs['timeout'] = self.timeout
Expand All @@ -768,8 +788,8 @@ def http_request(
response = super()._http_request( # type: ignore[misc]
*args, resp_type="response", headers=default_headers, **kwargs)

if should_http_retry_on_rate_limit and self.is_command_executed_from_integration():
self.create_api_metrics(response.status_code)
if should_http_retry_on_rate_limit and MicrosoftClient.is_command_executed_from_integration():
MicrosoftClient.create_api_metrics(response.status_code)
# 206 indicates Partial Content, reason will be in the warning header.
# In that case, logs with the warning header will be written.
if response.status_code == 206:
Expand Down Expand Up @@ -802,7 +822,7 @@ def http_request(
else:
demisto.info(f'Scheduling command {demisto.command()}')
command_args['ran_once_flag'] = True
return_results(self.run_retry_on_rate_limit(command_args))
return_results(MicrosoftClient.run_retry_on_rate_limit(command_args))
sys.exit(0)

try:
Expand Down Expand Up @@ -831,8 +851,8 @@ def get_access_token(self, resource: str = '', scope: str | None = None) -> str:
integration context.

Args:
resource (str): The resource identifier for which the generated token will have access to.
scope (str): A scope to get instead of the default on the API.
resource: The resource identifier for which the generated token will have access to.
scope: A scope to get instead of the default on the API.

Returns:
str: Access token that will be added to authorization header.
Expand All @@ -852,10 +872,15 @@ def get_access_token(self, resource: str = '', scope: str | None = None) -> str:

if self.auth_type == OPROXY_AUTH_TYPE:
if self.multi_resource:
expires_in = None
for resource_str in self.resources:
access_token, expires_in, refresh_token = self._oproxy_authorize(resource_str)
access_token, current_expires_in, refresh_token = self._oproxy_authorize(resource_str)
self.resource_to_access_token[resource_str] = access_token
self.refresh_token = refresh_token
expires_in = current_expires_in if expires_in is None else \
min(expires_in, current_expires_in) # type: ignore[call-overload]
if expires_in is None:
raise DemistoException("No resource was provided to get access token from")
else:
access_token, expires_in, refresh_token = self._oproxy_authorize(scope=scope)

Expand Down Expand Up @@ -988,14 +1013,13 @@ def _get_self_deployed_token(self,
if self.grant_type == AUTHORIZATION_CODE:
if not self.multi_resource:
return self._get_self_deployed_token_auth_code(refresh_token, scope=scope)
else:
expires_in = -1 # init variable as an int
for resource in self.resources:
access_token, expires_in, refresh_token = self._get_self_deployed_token_auth_code(refresh_token,
resource)
self.resource_to_access_token[resource] = access_token
expires_in = -1 # init variable as an int
for resource in self.resources:
access_token, expires_in, refresh_token = self._get_self_deployed_token_auth_code(refresh_token,
resource)
self.resource_to_access_token[resource] = access_token

return '', expires_in, refresh_token
return '', expires_in, refresh_token
elif self.grant_type == DEVICE_CODE:
return self._get_token_device_code(refresh_token, scope, integration_context)
else:
Expand Down Expand Up @@ -1033,7 +1057,7 @@ def _get_self_deployed_token_client_credentials(self, scope: str | None = None,

# Set scope.
if self.scope or scope:
data['scope'] = scope if scope else self.scope
data['scope'] = scope or self.scope

if self.resource or resource:
data['resource'] = resource or self.resource # type: ignore
Expand Down Expand Up @@ -1177,16 +1201,18 @@ def _get_refresh_token_from_auth_code_param(self) -> str:
return self.auth_code[len(refresh_prefix):]
return ''

def run_retry_on_rate_limit(self, args_for_next_run: dict):
@staticmethod
def run_retry_on_rate_limit(args_for_next_run: dict):
return CommandResults(readable_output="Rate limit reached, rerunning the command in 1 min",
scheduled_command=ScheduledCommand(command=demisto.command(), next_run_in_seconds=60,
args=args_for_next_run))

def handle_error_with_metrics(self, res):
self.create_api_metrics(res.status_code)
MicrosoftClient.create_api_metrics(res.status_code)
self.client_error_handler(res)

def create_api_metrics(self, status_code):
@staticmethod
def create_api_metrics(status_code):
execution_metrics = ExecutionMetrics()
ok_codes = (200, 201, 202, 204, 206)

Expand Down Expand Up @@ -1262,14 +1288,14 @@ def epoch_seconds(d: datetime = None) -> int:
"""
if not d:
d = MicrosoftClient._get_utcnow()
return int((d - MicrosoftClient._get_utcfromtimestamp(0)).total_seconds())
return int((d - MicrosoftClient._get_utc_from_timestamp(0)).total_seconds())

@staticmethod
def _get_utcnow() -> datetime:
return datetime.utcnow()

@staticmethod
def _get_utcfromtimestamp(_time) -> datetime:
def _get_utc_from_timestamp(_time) -> datetime:
return datetime.utcfromtimestamp(_time)

@staticmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def test_page_not_found_error(mocker):

def test_epoch_seconds(mocker):
mocker.patch.object(MicrosoftClient, '_get_utcnow', return_value=datetime.datetime(2019, 12, 24, 14, 12, 0, 586636))
mocker.patch.object(MicrosoftClient, '_get_utcfromtimestamp', return_value=datetime.datetime(1970, 1, 1, 0, 0))
mocker.patch.object(MicrosoftClient, '_get_utc_from_timestamp', return_value=datetime.datetime(1970, 1, 1, 0, 0))
integer = MicrosoftClient.epoch_seconds()
assert integer == 1577196720

Expand Down Expand Up @@ -522,8 +522,7 @@ def test_create_api_metrics(mocker, response, result):
mocker.patch('CommonServerPython.is_demisto_version_ge', return_value=True)
mocker.patch('MicrosoftApiModule.is_demisto_version_ge', return_value=True)
mocker.patch.object(demisto, 'callingContext', {'context': {'ExecutedCommands': [{'moduleBrand': 'msgraph'}]}})
client = retry_on_rate_limit_client(True)
client.create_api_metrics(response)
MicrosoftClient.create_api_metrics(response)

metric_results = demisto.results.call_args_list[0][0][0]
assert metric_results.get('Contents') == 'Metrics reported successfully.'
Expand Down
6 changes: 6 additions & 0 deletions Packs/AzureActiveDirectory/ReleaseNotes/1_3_15.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

#### Integrations

##### Azure Active Directory Identity Protection (Deprecated)

- Added support for Microsoft Defender for Application Endpoints in the Microsoft API Module.
2 changes: 1 addition & 1 deletion Packs/AzureActiveDirectory/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Deprecated. Use Microsoft Graph Identity and Access instead.",
"support": "xsoar",
"hidden": true,
"currentVersion": "1.3.14",
"currentVersion": "1.3.15",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
7 changes: 7 additions & 0 deletions Packs/AzureCompute/ReleaseNotes/1_2_12.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#### Integrations

##### Azure Compute v2

- Added support for Microsoft Defender for Application Endpoints in the Microsoft API Module.
- Updated the Docker image to: *demisto/crypto:1.0.0.66562*.
2 changes: 1 addition & 1 deletion Packs/AzureCompute/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Azure Compute",
"description": "Create and Manage Azure Virtual Machines",
"support": "xsoar",
"currentVersion": "1.2.11",
"currentVersion": "1.2.12",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
7 changes: 7 additions & 0 deletions Packs/AzureDataExplorer/ReleaseNotes/1_2_24.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#### Integrations

##### Azure Data Explorer

- Added support for Microsoft Defender for Application Endpoints in the Microsoft API Module.
- Updated the Docker image to: *demisto/azure-kusto-data:1.0.0.66840*.
2 changes: 1 addition & 1 deletion Packs/AzureDataExplorer/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.23",
"currentVersion": "1.2.24",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
7 changes: 7 additions & 0 deletions Packs/AzureDevOps/ReleaseNotes/1_2_16.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#### Integrations

##### AzureDevOps

- Added support for Microsoft Defender for Application Endpoints in the Microsoft API Module.
- Updated the Docker image to: *demisto/crypto:1.0.0.66562*.
2 changes: 1 addition & 1 deletion Packs/AzureDevOps/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "AzureDevOps",
"description": "Create and manage Git repositories in Azure DevOps Services.",
"support": "xsoar",
"currentVersion": "1.2.15",
"currentVersion": "1.2.16",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
7 changes: 7 additions & 0 deletions Packs/AzureFirewall/ReleaseNotes/1_1_24.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#### Integrations

##### Azure Firewall

- Added support for Microsoft Defender for Application Endpoints in the Microsoft API Module.
- Updated the Docker image to: *demisto/crypto:1.0.0.66562*.
2 changes: 1 addition & 1 deletion Packs/AzureFirewall/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.23",
"currentVersion": "1.1.24",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def __init__(self, tenant_id: str, client_id: str, client_secret: str,
private_key=private_key,
managed_identities_client_id=managed_identities_client_id,
command_prefix="azure-key-vault",
azure_cloud=self.azure_cloud,
)

def get_vault_resource(self) -> str:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ configuration:
required: false
- additionalinfo: Used for certificate authentication. As appears in the "Certificates & secrets" page of the app.
displaypassword: Certificate Thumbprint
name: credentials_certificate_thumbprint
name: credentials_certificate_thumbprint
required: false
hiddenusername: true
type: 9
Expand Down Expand Up @@ -964,7 +964,7 @@ script:
description: Run this command if for some reason you need to rerun the authentication process.
execution: false
name: azure-key-vault-auth-reset
dockerimage: demisto/crypto:1.0.0.66562
dockerimage: demisto/crypto:1.0.0.67955
runonce: false
script: '-'
subtype: python3
Expand Down
7 changes: 7 additions & 0 deletions Packs/AzureKeyVault/ReleaseNotes/1_1_25.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#### Integrations

##### Azure Key Vault
- Updated the Docker image to: *demisto/crypto:1.0.0.67955*.
- Added support for Microsoft Defender for Application Endpoints in the Microsoft API Module.
- Fixed an issue where the Azure cloud settings wasn't passed correctly to the API Module.
2 changes: 1 addition & 1 deletion Packs/AzureKeyVault/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.24",
"currentVersion": "1.1.25",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def __init__(self, app_id: str, subscription_id: str, resource_group_name: str,
managed_identities_client_id=managed_identities_client_id,
managed_identities_resource_uri=Resources.management_azure,
command_prefix="azure-ks",
azure_cloud=azure_cloud,
)
self.ms_client = MicrosoftClient(**client_args)
self.subscription_id = subscription_id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ script:
- contextPath: AzureKS.ResourceGroup.tags.type
description: 'The type tag associated with the Azure Kubernetes resource group.'
type: String
dockerimage: demisto/crypto:1.0.0.66562
dockerimage: demisto/crypto:1.0.0.67955
runonce: false
script: '-'
subtype: python3
Expand Down
7 changes: 7 additions & 0 deletions Packs/AzureKubernetesServices/ReleaseNotes/1_1_17.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#### Integrations

##### Azure Kubernetes Services
- Updated the Docker image to: *demisto/crypto:1.0.0.67955*.
- Added support for Microsoft Defender for Application Endpoints in the Microsoft API Module.
- Fixed an issue where the Azure cloud settings wasn't passed correctly to the API Module.
2 changes: 1 addition & 1 deletion Packs/AzureKubernetesServices/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.16",
"currentVersion": "1.1.17",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down
7 changes: 7 additions & 0 deletions Packs/AzureLogAnalytics/ReleaseNotes/1_1_15.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

#### Integrations

##### Azure Log Analytics

- Added support for Microsoft Defender for Application Endpoints in the Microsoft API Module.
- Updated the Docker image to: *demisto/crypto:1.0.0.66562*.
2 changes: 1 addition & 1 deletion Packs/AzureLogAnalytics/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.14",
"currentVersion": "1.1.15",
"author": "Cortex XSOAR",
"url": "https://www.paloaltonetworks.com/cortex",
"email": "",
Expand Down