From c89e76721dc6d59abcc03e6042150a546ede9e77 Mon Sep 17 00:00:00 2001 From: eset-enterpise-integration Date: Mon, 18 Nov 2024 14:55:34 +0100 Subject: [PATCH 1/3] ESET Protect Platform Solution 3.0.1 --- .../CustomTables/IntegrationTable_CL.json | 174 ++++++++++++------ .../ESETProtectPlatform_API_FunctionApp.json | 2 +- .../FunctionAppESETProtectPlatform.zip | Bin 11779418 -> 11780729 bytes ...y_ESETProtectPlatform_API_FunctionApp.json | 154 ++++++++++++++-- .../Data Connectors/integration/main.py | 122 ++++++++---- .../Data Connectors/integration/models.py | 9 +- .../integration/models_detections.py | 84 ++++++++- .../Data Connectors/integration/utils.py | 129 ++++++++----- .../Data/Solution_ESETProtectPlatform.json | 3 + .../ESET Protect Platform/Package/3.0.1.zip | Bin 0 -> 7402 bytes .../Package/createUiDefinition.json | 9 +- .../Package/mainTemplate.json | 158 +++++++++++++++- .../Parsers/ESETProtectPlatform.yaml | 53 ++++++ .../SolutionMetadata.json | 4 +- 14 files changed, 723 insertions(+), 178 deletions(-) create mode 100644 Solutions/ESET Protect Platform/Package/3.0.1.zip create mode 100644 Solutions/ESET Protect Platform/Parsers/ESETProtectPlatform.yaml diff --git a/.script/tests/KqlvalidationsTests/CustomTables/IntegrationTable_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/IntegrationTable_CL.json index 5a374ae0890..1da49c938f5 100644 --- a/.script/tests/KqlvalidationsTests/CustomTables/IntegrationTable_CL.json +++ b/.script/tests/KqlvalidationsTests/CustomTables/IntegrationTable_CL.json @@ -1,61 +1,121 @@ { "Name": "IntegrationTable_CL", "Properties": [ - { - "name": "TimeGenerated", - "type": "datetime" - }, - { - "name": "typeName", - "type": "string" - }, - { - "name": "objectName", - "type": "string" - }, - { - "name": "networkCommunication", - "type": "dynamic" - }, - { - "name": "customUuid", - "type": "string" - }, - { - "name": "objectTypeName", - "type": "string" - }, - { - "name": "occurTime", - "type": "string" - }, - { - "name": "displayName", - "type": "string" - }, - { - "name": "responses", - "type": "dynamic" - }, - { - "name": "objectHashSha1", - "type": "string" - }, - { - "name": "severityLevel", - "type": "string" - }, - { - "name": "category", - "type": "string" - }, - { - "name": "objectUrl", - "type": "string" - }, - { - "name": "context", - "type": "dynamic" - } - ] + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "typeName", + "type": "string" + }, + { + "name": "objectName", + "type": "string" + }, + { + "name": "networkCommunication", + "type": "dynamic" + }, + { + "name": "detectionUuid", + "type": "dynamic" + }, + { + "name": "objectTypeName", + "type": "string" + }, + { + "name": "occurTime", + "type": "string" + }, + { + "name": "displayName", + "type": "string" + }, + { + "name": "responses", + "type": "dynamic" + }, + { + "name": "objectHashSha1", + "type": "string" + }, + { + "name": "severityLevel", + "type": "string" + }, + { + "name": "category", + "type": "string" + }, + { + "name": "objectUrl", + "type": "string" + }, + { + "name": "context", + "type": "dynamic" + }, + { + "name": "groupSize", + "type": "int" + }, + { + "name": "severityScore", + "type": "string" + }, + { + "name": "deviceDisplayName", + "type": "string" + }, + { + "name": "deviceUuid", + "type": "string" + }, + { + "name": "userNameBase", + "type": "string" + }, + { + "name": "processPath", + "type": "string" + }, + { + "name": "processUuid", + "type": "string" + }, + { + "name": "processCommandline", + "type": "string" + }, + { + "name": "objectSizeBytes", + "type": "int" + }, + { + "name": "edrRuleUuid", + "type": "string" + }, + { + "name": "note", + "type": "string" + }, + { + "name": "resolved", + "type": "boolean" + }, + { + "name": "cloudOfficeTenantUuid", + "type": "string" + }, + { + "name": "scanUuid", + "type": "string" + }, + { + "name": "triggeringEvent", + "type": "dynamic" + } + ] } \ No newline at end of file diff --git a/Solutions/ESET Protect Platform/Data Connectors/ESETProtectPlatform_API_FunctionApp.json b/Solutions/ESET Protect Platform/Data Connectors/ESETProtectPlatform_API_FunctionApp.json index fa05bc9d046..362c3c3540f 100644 --- a/Solutions/ESET Protect Platform/Data Connectors/ESETProtectPlatform_API_FunctionApp.json +++ b/Solutions/ESET Protect Platform/Data Connectors/ESETProtectPlatform_API_FunctionApp.json @@ -70,7 +70,7 @@ }, { "title": "Step 2 - Create a registered application", - "description": "Create a Microsoft Entra ID registered application by following the steps in the [Register a new application instruction.](https://learn.microsoft.com/en-us/azure/healthcare-apis/register-application#register-a-new-application)" + "description": "Create a Microsoft Entra ID registered application by following the steps in the [Register a new application instruction.](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)" }, { "title": "Step 3 - Deploy the ESET Protect Platform data connector using the Azure Resource Manager (ARM) template", diff --git a/Solutions/ESET Protect Platform/Data Connectors/FunctionAppESETProtectPlatform.zip b/Solutions/ESET Protect Platform/Data Connectors/FunctionAppESETProtectPlatform.zip index dbcc365aed0d3b8d53896e1f58975b01f69f81ad..142211ad90ff9cb38579ca95404f53886b3e1267 100644 GIT binary patch delta 68764 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 O!@rT74fi}Q1^RzuzrND| diff --git a/Solutions/ESET Protect Platform/Data Connectors/azuredeploy_ESETProtectPlatform_API_FunctionApp.json b/Solutions/ESET Protect Platform/Data Connectors/azuredeploy_ESETProtectPlatform_API_FunctionApp.json index f39e2ca2a64..39dc94319e4 100644 --- a/Solutions/ESET Protect Platform/Data Connectors/azuredeploy_ESETProtectPlatform_API_FunctionApp.json +++ b/Solutions/ESET Protect Platform/Data Connectors/azuredeploy_ESETProtectPlatform_API_FunctionApp.json @@ -13,27 +13,31 @@ "metadata": { "description": "The name of the custom Log Analytics table to be created." }, - "defaultValue": "IntegrationTable_CL" + "defaultValue": "IntegrationTable_CL", + "minLength": 3 }, "dataCollectionEndpointName": { "type": "string", "metadata": { "description": "The name of the Data Collection Endpoint to be created." }, - "defaultValue": "integrationDCE" + "defaultValue": "integrationDCE", + "minLength": 3 }, "dataCollectionRuleName": { "type": "string", "metadata": { "description": "The name of the Data Collection Rule to be created." }, - "defaultValue": "integrationDCR" + "defaultValue": "integrationDCR", + "minLength": 3 }, "applicationName": { "type": "string", "metadata": { - "description": "The name of the Azure Function App to be created." - } + "description": "The name of the Azure Function App to be created. The name must be a unique value. Therefore, the system will add additional characters from your Resource group ID to the name you provide to ensure its uniqueness." + }, + "minLength": 3 }, "applicationRunInterval": { "type": "int", @@ -74,7 +78,7 @@ "login": { "type": "string", "metadata": { - "description": "The ESET Connect API user account login." + "description": "The ESET Connect API user account login (email)." } }, "password": { @@ -102,7 +106,9 @@ "defaultValue": "[newGuid()]", "metadata": { "description": "Do not change this value. Base string for the key to encrypt/decrypt token data." - } + }, + "minLength": 36, + "maxLength": 36 } }, "variables": { @@ -116,7 +122,7 @@ "contentShare": "[variables('applicationName')]", "storageAccountName": "[concat(uniquestring(resourceGroup().id), 'azfunction')]", "workspaces_integration_log_analytics_workspace_externalid":"[resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceName'))]", - "keyBase64": "[base64(replace(parameters('keyBase'), '-', ''))]" + "keyBase64": "[base64(substring(parameters('keyBase'), 0, 32))]" }, "resources": [ @@ -133,7 +139,7 @@ "publicNetworkAccess": "Enabled" } } - }, + }, { "type": "Microsoft.OperationalInsights/workspaces/tables", "apiVersion": "2022-10-01", @@ -160,8 +166,8 @@ "type": "dynamic" }, { - "name": "customUuid", - "type": "string" + "name": "detectionUuid", + "type": "dynamic" }, { "name": "objectTypeName", @@ -198,11 +204,71 @@ { "name": "context", "type": "dynamic" + }, + { + "name": "groupSize", + "type": "int" + }, + { + "name": "severityScore", + "type": "string" + }, + { + "name": "deviceDisplayName", + "type": "string" + }, + { + "name": "deviceUuid", + "type": "string" + }, + { + "name": "userNameBase", + "type": "string" + }, + { + "name": "processPath", + "type": "string" + }, + { + "name": "processUuid", + "type": "string" + }, + { + "name": "processCommandline", + "type": "string" + }, + { + "name": "objectSizeBytes", + "type": "int" + }, + { + "name": "edrRuleUuid", + "type": "string" + }, + { + "name": "note", + "type": "string" + }, + { + "name": "resolved", + "type": "boolean" + }, + { + "name": "cloudOfficeTenantUuid", + "type": "string" + }, + { + "name": "scanUuid", + "type": "string" + }, + { + "name": "triggeringEvent", + "type": "dynamic" } ] } } - }, + }, { "type": "Microsoft.Insights/dataCollectionRules", "apiVersion": "2023-03-11", @@ -234,8 +300,8 @@ "type": "dynamic" }, { - "name": "customUuid", - "type": "string" + "name": "detectionUuid", + "type": "dynamic" }, { "name": "objectTypeName", @@ -272,6 +338,66 @@ { "name": "context", "type": "dynamic" + }, + { + "name": "groupSize", + "type": "int" + }, + { + "name": "severityScore", + "type": "string" + }, + { + "name": "deviceDisplayName", + "type": "string" + }, + { + "name": "deviceUuid", + "type": "string" + }, + { + "name": "userNameBase", + "type": "string" + }, + { + "name": "processPath", + "type": "string" + }, + { + "name": "processUuid", + "type": "string" + }, + { + "name": "processCommandline", + "type": "string" + }, + { + "name": "objectSizeBytes", + "type": "int" + }, + { + "name": "edrRuleUuid", + "type": "string" + }, + { + "name": "note", + "type": "string" + }, + { + "name": "resolved", + "type": "boolean" + }, + { + "name": "cloudOfficeTenantUuid", + "type": "string" + }, + { + "name": "scanUuid", + "type": "string" + }, + { + "name": "triggeringEvent", + "type": "dynamic" } ] } diff --git a/Solutions/ESET Protect Platform/Data Connectors/integration/main.py b/Solutions/ESET Protect Platform/Data Connectors/integration/main.py index fb6547ad842..821f61282e1 100644 --- a/Solutions/ESET Protect Platform/Data Connectors/integration/main.py +++ b/Solutions/ESET Protect Platform/Data Connectors/integration/main.py @@ -4,6 +4,8 @@ import typing as t from datetime import datetime, timezone +from aiohttp import ClientSession + from integration.models import Config, EnvVariables, TokenStorage from integration.utils import ( LastDetectionTimeHandler, @@ -17,55 +19,96 @@ class ServiceClient: def __init__(self) -> None: self.config = Config() self.env_vars = EnvVariables() - self.last_detection_time_handler = LastDetectionTimeHandler( - self.env_vars.conn_str, - self.env_vars.last_detection_time, - ) self.request_sender = RequestSender(self.config, self.env_vars) self.token_provider = TokenProvider(TokenStorage(), self.request_sender, self.env_vars, self.config.buffer) self.transformer_detections = TransformerDetections(self.env_vars) - self._is_running = False - self._next_page_token: str | None = None - self._cur_ld_time: str | None = None + self._session: ClientSession | None = None + self.lock = asyncio.Lock() - async def run(self) -> None: - if self._is_running: - while self._is_running: - await asyncio.gather(self._custom_sleep(), self._process_integration()) - else: - await asyncio.gather(self._process_integration()) + async def close(self) -> None: + if self._session and not self._session.closed: + await self._session.close() - async def _process_integration(self) -> None: + async def run(self) -> None: + self._session = ClientSession() start_time = time.time() + try: + await asyncio.gather( + self._process_integration("EI", start_time), self._process_integration("ECOS", start_time) + ) + except Exception as e: + logging.error("Unexpected error happened", exc_info=e) + raise e + finally: + await self.close() + + async def _process_integration(self, data_source: str, start_time: float) -> None: + last_detection_time_handler = LastDetectionTimeHandler( + self.env_vars.conn_str, self.env_vars.last_detection_time, data_source=data_source + ) + next_page_token: str | None = None + cur_ld_time: str | None = None max_duration = self.env_vars.interval * 60 - while self._next_page_token != "" and (time.time() - start_time) < (max_duration - 30): - response_data = await self._call_service() - self._next_page_token = response_data.get("nextPageToken") if response_data else "" + if data_source == "EI" and not last_detection_time_handler.storage_table_handler.entities: + data_source, last_detection_time_handler = await self._check_if_ei_is_right_data_source( + last_detection_time_handler, next_page_token + ) + endp = self.config.data_sources.get(data_source).get("endpoint") # type: ignore - if response_data and response_data.get("detections") and (time.time() - start_time) < (max_duration - 15): - self._cur_ld_time, successful_data_upload = ( - await self.transformer_detections.send_integration_detections(response_data, self._cur_ld_time) - ) - self._next_page_token = "" if successful_data_upload is False else self._next_page_token - self._update_last_detection_time() + while next_page_token != "" and (time.time() - start_time) < (max_duration - 30): + response_data = await self._call_service(last_detection_time_handler, next_page_token, data_endpoint=endp) + next_page_token = response_data.get("nextPageToken") if response_data else "" - def _update_last_detection_time(self) -> None: - if self._cur_ld_time and self._cur_ld_time != self.last_detection_time_handler.last_detection_time: - self.last_detection_time_handler.storage_table_handler.input_entity( - new_entity=self.last_detection_time_handler.get_entity_schema(self._cur_ld_time) # type: ignore[call-arg] + if ( + response_data + and (response_data.get("detections") or response_data.get("detectionGroups")) + and (time.time() - start_time) < (max_duration - 15) + ): + cur_ld_time, successful_data_upload = await self.transformer_detections.send_integration_detections( + response_data, cur_ld_time + ) + next_page_token = "" if successful_data_upload is False else next_page_token + self._update_last_detection_time(last_detection_time_handler, cur_ld_time) + + async def _check_if_ei_is_right_data_source( + self, + last_detection_time_handler: LastDetectionTimeHandler, + next_page_token: str | None, + data_source: str = "EI", + ) -> tuple[str, LastDetectionTimeHandler]: + endp = self.config.data_sources.get(data_source).get("endpoint") # type: ignore + response_data = await self._call_service( + last_detection_time_handler, next_page_token, page_size=1, data_endpoint=endp + ) + if not response_data or not response_data.get("detectionGroups"): + data_source, last_detection_time_handler = ( + "EP", + LastDetectionTimeHandler(self.env_vars.conn_str, self.env_vars.last_detection_time, data_source="EP"), ) - async def _custom_sleep(self) -> None: - logging.info(f"Start of the {self.env_vars.interval} seconds interval") - await asyncio.sleep(self.env_vars.interval) - logging.info(f"End of the {self.env_vars.interval} seconds interval") + return data_source, last_detection_time_handler + + def _update_last_detection_time( + self, last_detection_time_handler: LastDetectionTimeHandler, cur_ld_time: str | None + ) -> None: + if cur_ld_time and cur_ld_time != last_detection_time_handler.last_detection_time: + last_detection_time_handler.storage_table_handler.input_entity( + new_entity=last_detection_time_handler.get_entity_schema(cur_ld_time) # type: ignore[call-arg] + ) - async def _call_service(self) -> dict[str, t.Any] | None: + async def _call_service( + self, + last_detection_time_handler: LastDetectionTimeHandler, + next_page_token: str | None, + page_size: int = 100, + data_endpoint: str = "", + ) -> dict[str, t.Any] | None: logging.info(f"Service call initiated") if not self.token_provider.token.access_token or datetime.now(timezone.utc) > self.token_provider.token.expiration_time: # type: ignore - await self.token_provider.get_token() + assert self._session + await self.token_provider.get_token(self._session, self.lock) try: if ( @@ -74,16 +117,19 @@ async def _call_service(self) -> dict[str, t.Any] | None: ): data = await self.request_sender.send_request( self.request_sender.send_request_get, + self._session, # type: ignore { "Authorization": f"Bearer {self.token_provider.token.access_token}", "Content-Type": "application/json", + "3rd-integration": "MS-Sentinel", }, - self.last_detection_time_handler.last_detection_time, - self._next_page_token, - ) - logging.info( - f"Service call response data is {'obtained' if data and data.get('detections') else f'empty: {data}'}" + last_detection_time_handler.last_detection_time, + next_page_token, + page_size, + data_endpoint, ) + is_obtained = True if data and (data.get("detections") or data.get("detectionGroups")) else False + logging.info(f"Service call response data is {'obtained' if is_obtained else f'empty: {data}'}") return data logging.info("Service not called due to missing token.") diff --git a/Solutions/ESET Protect Platform/Data Connectors/integration/models.py b/Solutions/ESET Protect Platform/Data Connectors/integration/models.py index afbba7d4309..dbc2d9788e4 100644 --- a/Solutions/ESET Protect Platform/Data Connectors/integration/models.py +++ b/Solutions/ESET Protect Platform/Data Connectors/integration/models.py @@ -54,11 +54,12 @@ def __init__(self) -> None: self.retry_delay: float = float(config.get("retry_delay")) # type: ignore self.requests_timeout = config.get("requests_timeout") self.buffer: int = config.get("buffer") # type: ignore + self.data_sources: dict[str, t.Any] = config.get("data_sources") # type: ignore def get_config_params(self) -> dict[str, t.Any] | t.Any: try: return yaml.safe_load( - resources.files(__package__ or "integration").parent.joinpath("config.yml").read_bytes() + resources.files(__package__ or "integration").parent.joinpath("config.yml").read_bytes() # type: ignore ) except FileNotFoundError as e: logging.error(e) @@ -80,9 +81,11 @@ def __init__(self) -> None: self.__conn_str: str = os.getenv("WEBSITE_CONTENTAZUREFILECONNECTIONSTRING", "") self.__key_base64: str = os.getenv("KEY_BASE64", "") - region = os.getenv("INSTANCE_REGION", "") + region = os.getenv("INSTANCE_REGION", "eu") self.oauth_url: str = f"https://{region}.business-account.iam.eset.systems" - self.detections_url: str = f"https://{region}.incident-management.eset.systems/v1/detections" + self.detections_url: str = ( + f"https://{region}.incident-management.eset.systems" + ) @property def username(self) -> str | None: diff --git a/Solutions/ESET Protect Platform/Data Connectors/integration/models_detections.py b/Solutions/ESET Protect Platform/Data Connectors/integration/models_detections.py index 2684ba196de..c6c55bae1cd 100644 --- a/Solutions/ESET Protect Platform/Data Connectors/integration/models_detections.py +++ b/Solutions/ESET Protect Platform/Data Connectors/integration/models_detections.py @@ -1,6 +1,7 @@ +import typing as t from datetime import datetime -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, computed_field, field_validator class NetworkCommunication(BaseModel): @@ -24,11 +25,30 @@ class Response(BaseModel): deviceRestartRequired: bool displayName: str protectionName: str + actionType: t.Optional[str] = "" + + +class Device(BaseModel): + displayName: str + uuid: str + + +class Process(BaseModel): + commandLine: str + path: str + uuid: str + + +class TriggeringEvent(BaseModel): + type: str + data: t.Optional[dict[str, t.Any]] class Detection(BaseModel): - context: Context - networkCommunication: NetworkCommunication + device: t.Optional[Device] = Field(default=None, exclude=True) + process: t.Optional[Process] = Field(default=None, exclude=True) + context: t.Optional[Context] = Field(default=None, exclude=True) + networkCommunication: t.Optional[NetworkCommunication] = None responses: list[Response] category: str displayName: str @@ -40,10 +60,62 @@ class Detection(BaseModel): TimeGenerated: str = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") severityLevel: str typeName: str - customUuid: str = Field(alias="uuid") + customUuid: str = Field(alias="uuid", exclude=True) + detectionOccurenceUuids: t.Optional[list[str]] = Field(default=None, exclude=True) + groupSize: int = 1 + severityScore: t.Optional[str] = None + userName: t.Optional[str] = "" + objectSizeBytes: t.Optional[int] = None + edrRuleUuid: t.Optional[str] = None + note: t.Optional[str] = None + resolved: t.Optional[bool] = None + cloudOfficeTenantUuid: t.Optional[str] = None + scanUuid: t.Optional[str] = None + triggeringEvent: t.Optional[TriggeringEvent] = None + + @computed_field(return_type=str | list[str]) + def detectionUuid(self) -> str | list[str]: + return self.detectionOccurenceUuids if self.detectionOccurenceUuids else self.customUuid + + @computed_field(return_type=str | None) + def deviceDisplayName(self)-> str | None : + return self.device.displayName if self.device else None + + @computed_field(return_type=str | None) + def deviceUuid(self)-> str | None: + if self.device: + return self.device.uuid + elif self.context: + return self.context.deviceUuid + return None + + @computed_field(return_type=str | None) + def userNameBase(self)-> str | None: + return self.context.userName if self.context else self.userName + + @computed_field(return_type=str | None) + def processPath(self)-> str | None: + if self.process: + return self.process.path + elif self.context: + return self.context.process.get("path") + return None + + @computed_field(return_type=str | None) + def processUuid(self)-> str | None: + return self.process.uuid if self.process else None + + @computed_field(return_type=str | None) + def processCommandline(self)-> str | None: + return self.process.commandLine if self.process else None + + @field_validator('severityScore', mode='before') + @classmethod + def convert_int_to_str(cls, v: int | str | None) -> str | int | None: + return str(v) if isinstance(v, int) else v class Detections(BaseModel): detections: list[Detection] - nextPageToken: str - totalSize: int + nextPageToken: str = Field(exclude=True) + totalSize: t.Optional[int] = Field(default=None, exclude=True) diff --git a/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py b/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py index 485561765a1..b62801d1e88 100644 --- a/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py +++ b/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py @@ -4,13 +4,15 @@ import urllib.parse from datetime import datetime, timedelta, timezone -import aiohttp +from aiohttp import ClientSession from aiohttp.client_exceptions import ClientResponseError from azure.core.exceptions import HttpResponseError, ServiceRequestError from azure.data.tables import TableServiceClient from azure.identity.aio import DefaultAzureCredential from azure.monitor.ingestion.aio import LogsIngestionClient from cryptography.fernet import Fernet, InvalidToken +from pydantic import ValidationError + from integration.exceptions import ( AuthenticationException, InvalidCredentialsException, @@ -19,7 +21,6 @@ ) from integration.models import Config, EnvVariables, TokenStorage from integration.models_detections import Detection, Detections -from pydantic import ValidationError class RequestSender: @@ -31,12 +32,15 @@ async def send_request( self, send_request_fun: ( t.Callable[ - [aiohttp.client.ClientSession, str, str | None], t.Coroutine[t.Any, t.Any, dict[str, str | int] | t.Any] + [ClientSession, dict[str, t.Any] | None, str, str | None, int, str], + t.Coroutine[t.Any, t.Any, dict[str, str | int] | t.Any], ] | t.Callable[ - [aiohttp.client.ClientSession, str | None], t.Coroutine[t.Any, t.Any, dict[str, str | int] | t.Any] + [ClientSession, dict[str, t.Any] | None, str | None], + t.Coroutine[t.Any, t.Any, dict[str, str | int] | t.Any], ] ), + session: ClientSession, headers: dict[str, t.Any] | None = None, *data: t.Any, ) -> t.Dict[str, str | int] | None: @@ -44,8 +48,7 @@ async def send_request( while retries < self.config.max_retries: try: - async with aiohttp.ClientSession(headers=headers, raise_for_status=True) as session: - return await send_request_fun(session, *data) + return await send_request_fun(session, headers, *data) except ClientResponseError as e: if e.status in [400, 401, 403]: @@ -60,29 +63,42 @@ async def send_request( return None async def send_request_post( - self, session: aiohttp.client.ClientSession, grant_type: str | None + self, session: ClientSession, headers: dict[str, t.Any] | None, grant_type: str | None ) -> t.Dict[str, str | int] | t.Any: logging.info("Sending token request") async with session.post( url=f"{self.env_vars.oauth_url}/oauth/token", + headers=headers, data=urllib.parse.quote(f"grant_type={grant_type}", safe="=&/"), timeout=self.config.requests_timeout, ) as response: + response.raise_for_status() return await response.json() async def send_request_get( - self, session: aiohttp.client.ClientSession, last_detection_time: str, next_page_token: str | None + self, + session: ClientSession, + headers: dict[str, t.Any] | None, + last_detection_time: str, + next_page_token: str | None, + page_size: int, + data_endpoint: str, ) -> t.Dict[str, str | int] | t.Any: logging.info("Sending service request") async with session.get( - self.env_vars.detections_url, params=self._prepare_get_request_params(last_detection_time, next_page_token) + self.env_vars.detections_url + data_endpoint, + headers=headers, + params=self._prepare_get_request_params(last_detection_time, next_page_token, page_size), ) as response: + response.raise_for_status() return await response.json() - def _prepare_get_request_params(self, last_detection_time: str, next_page_token: str | None) -> dict[str, t.Any]: - params = {"pageSize": 100} + def _prepare_get_request_params( + self, last_detection_time: str, next_page_token: str | None, page_size: int = 100 + ) -> dict[str, t.Any]: + params = {"pageSize": page_size} if next_page_token not in ["", None]: params["pageToken"] = next_page_token # type: ignore[assignment] if last_detection_time: @@ -117,34 +133,38 @@ def get_token_params_from_storage(self) -> None: value = "" setattr(self.token, token_param, value) - async def get_token(self) -> None: - logging.info("Getting token") + async def get_token(self, session: ClientSession, lock: asyncio.Lock) -> None: + async with lock: - if not self.token.access_token and (not self.env_vars.username or not self.env_vars.password): - raise MissingCredentialsException() + if not self.token.access_token or datetime.now(timezone.utc) > self.token.expiration_time: # type: ignore + logging.info(f"Getting token") - grant_type = ( - f"refresh_token&refresh_token={self.token.refresh_token}" - if self.token.access_token - else f"password&username={self.env_vars.username}&password={self.env_vars.password}" - ) + if not self.token.access_token and (not self.env_vars.username or not self.env_vars.password): + raise MissingCredentialsException() - try: - response = await self.requests_sender.send_request( - self.requests_sender.send_request_post, - {"Content-type": "application/x-www-form-urlencoded"}, - grant_type, - ) - except AuthenticationException as e: - if not self.token.access_token: - raise InvalidCredentialsException(e) - else: - self.storage_table_handler.input_entity({k: "" for k in self.token.to_dict()}) # type: ignore[call-arg] - raise TokenRefreshException(e) - - if response: - self.set_token_params_locally_and_in_storage(response) - logging.info("Token obtained successfully") + grant_type = ( + f"refresh_token&refresh_token={self.token.refresh_token}" + if self.token.access_token + else f"password&username={self.env_vars.username}&password={self.env_vars.password}" + ) + + try: + response = await self.requests_sender.send_request( + self.requests_sender.send_request_post, + session, + {"Content-type": "application/x-www-form-urlencoded", "3rd-integration": "MS-Sentinel"}, + grant_type, + ) + except AuthenticationException as e: + if not self.token.access_token: + raise InvalidCredentialsException(e) + else: + self.storage_table_handler.input_entity({k: "" for k in self.token.to_dict()}) # type: ignore[call-arg] + raise TokenRefreshException(e) + + if response: + self.set_token_params_locally_and_in_storage(response) + logging.info("Token obtained successfully") def set_token_params_locally_and_in_storage(self, response: t.Dict[str, str | int]) -> None: self.token.access_token = t.cast(str, response["access_token"]) @@ -172,40 +192,46 @@ async def send_integration_detections( return last_detection, False return await self._send_data_to_log_analytics_workspace(validated_detections, last_detection) - def _validate_detections_data(self, response_data: dict[str, t.Any] | None) -> list[Detection] | None: + def _validate_detections_data(self, response_data: dict[str, t.Any] | None) -> list[dict[str, t.Any]] | None: if not response_data: logging.info("No new detections") return None + + response_data["detections"] = ( + response_data.pop("detectionGroups") if "detectionGroups" in response_data else response_data["detections"] + ) try: - return Detections.model_validate(response_data).detections + validated_data = Detections.model_validate(response_data) + self._update_time_generated(validated_data.detections) + return validated_data.model_dump().get("detections") + except ValidationError as e: logging.error(e) validated_detections = [] + for detection in response_data.get("detections"): # type: ignore try: validated_detections.append(Detection.model_validate(detection)) except ValidationError as e: logging.error(e) - return validated_detections + self._update_time_generated(validated_detections) + return [d.model_dump() for d in validated_detections] async def _send_data_to_log_analytics_workspace( - self, validated_data: t.List[Detection], last_detection: str | None, successful_data_upload: bool = False + self, validated_data: t.List[dict[str, t.Any]], last_detection: str | None, successful_data_upload: bool = False ) -> tuple[str | None, bool]: credential = DefaultAzureCredential() # Env vars: AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID client = LogsIngestionClient(endpoint=self.env_vars.endpoint_uri, credential=credential, logging_enable=True) async with client: try: - self._update_time_generated(validated_data) - dumped_data = [d.model_dump() for d in validated_data] - await client.upload( rule_id=self.env_vars.dcr_immutableid, stream_name=self.env_vars.stream_name, - logs=dumped_data, # type: ignore[arg-type] + logs=validated_data, # type: ignore[arg-type] ) - last_detection = max(validated_data, key=lambda detection: detection.occurTime).occurTime + last_detection = max(validated_data, key=lambda detection: detection.get("occurTime")).get("occurTime") # type: ignore successful_data_upload = True except ServiceRequestError as e: logging.error(f"Authentication to Azure service failed: {e}") @@ -263,14 +289,15 @@ def input_entity(self, new_entity: dict[str, t.Any]) -> None: if self.entities else self.table_client.create_entity(entity=entity) ) + self.entities = next(self.table_client.query_entities(""), None) logging.info(f"Entity: {self.table_name_keys} updated") except Exception as e: print("Exception occurred:", e) class LastDetectionTimeHandler: - def __init__(self, storage_table_conn_str: str, env_last_occur_time: str) -> None: - self.storage_table_name = "LastDetectionTime" + def __init__(self, storage_table_conn_str: str, env_last_occur_time: str, data_source: str) -> None: + self.storage_table_name = f"LastDetectionTime{data_source}" self.storage_table_handler = StorageTableHandler(storage_table_conn_str, self.storage_table_name) self.storage_table_handler.set_entity() self.last_detection_time = self.get_last_occur_time(env_last_occur_time) @@ -283,7 +310,13 @@ def get_last_occur_time(self, env_last_occur_time: str) -> t.Any: def get_entity_schema(self, cur_last_detection_time: str) -> dict[str, t.Any]: return { self.storage_table_name: ( - datetime.strptime(cur_last_detection_time, "%Y-%m-%dT%H:%M:%SZ") + timedelta(seconds=1) + datetime.strptime( + self.transform_date_with_miliseconds_to_second(cur_last_detection_time), "%Y-%m-%dT%H:%M:%SZ" + ) + + timedelta(seconds=1) ).isoformat() + "Z" } + + def transform_date_with_miliseconds_to_second(self, cur_last_detection_time: str) -> str: + return cur_last_detection_time if len(cur_last_detection_time) == 20 else cur_last_detection_time[:-5] + "Z" diff --git a/Solutions/ESET Protect Platform/Data/Solution_ESETProtectPlatform.json b/Solutions/ESET Protect Platform/Data/Solution_ESETProtectPlatform.json index b6813c11bcf..8fd35f8c8ef 100644 --- a/Solutions/ESET Protect Platform/Data/Solution_ESETProtectPlatform.json +++ b/Solutions/ESET Protect Platform/Data/Solution_ESETProtectPlatform.json @@ -6,6 +6,9 @@ "Data Connectors": [ "Data Connectors/ESETProtectPlatform_API_FunctionApp.json" ], + "Parsers": [ + "Parsers/ESETProtectPlatform.yaml" + ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\ESET Protect Platform", "Version": "1.0.0", "Metadata": "SolutionMetadata.json", diff --git a/Solutions/ESET Protect Platform/Package/3.0.1.zip b/Solutions/ESET Protect Platform/Package/3.0.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..6dca74df90f545600baff5e22bb1e076a1ef09eb GIT binary patch literal 7402 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\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/ESET%20Protect%20Platform/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nESET Protect Platform solution for Microsoft Sentinel ingests detections from [ESET Protect Platform](https://www.eset.com/int/business/protect-platform/) using the provided [Integration REST API](https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/ESET%20Protect%20Platform/Data%20Connectors). \n\n**Underlying Microsoft Technologies used:**\n\nThe ESET Protect Platform solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\n\na. [Logs Ingestion API in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/logs-ingestion-api-overview)\n\nb. [Azure Functions](https://azure.microsoft.com/services/functions/#overview)\n\n\n\n**Data Connectors:** 1\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/ESET%20Protect%20Platform/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nESET Protect Platform solution for Microsoft Sentinel ingests detections from [ESET Protect Platform](https://www.eset.com/int/business/protect-platform/) using the provided [Integration REST API](https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/ESET%20Protect%20Platform/Data%20Connectors). \n\n**Underlying Microsoft Technologies used:**\n\nThe ESET Protect Platform solution takes a dependency on the following technologies, and some of these dependencies either may be in [Preview](https://azure.microsoft.com/support/legal/preview-supplemental-terms/) state or might result in additional ingestion or operational costs:\n\na. [Logs Ingestion API in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/logs-ingestion-api-overview)\n\nb. [Azure Functions](https://azure.microsoft.com/services/functions/#overview)\n\n\n\n**Data Connectors:** 1, **Parsers:** 1\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", "subscription": { "resourceProviders": [ "Microsoft.OperationsManagement/solutions", @@ -63,6 +63,13 @@ "text": "This Solution installs the data connector for ESET Protect Platform. You can get ESET Protect Platform custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." } }, + { + "name": "dataconnectors-parser-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "The Solution installs a parser that transforms the ingested data into Microsoft Sentinel normalized format. The normalized format enables better correlation of different types of data from different data sources to drive end-to-end outcomes seamlessly in security monitoring, hunting, incident investigation and response scenarios in Microsoft Sentinel." + } + }, { "name": "dataconnectors-link2", "type": "Microsoft.Common.TextBlock", diff --git a/Solutions/ESET Protect Platform/Package/mainTemplate.json b/Solutions/ESET Protect Platform/Package/mainTemplate.json index 75f6456cd17..90cd8f71313 100644 --- a/Solutions/ESET Protect Platform/Package/mainTemplate.json +++ b/Solutions/ESET Protect Platform/Package/mainTemplate.json @@ -31,7 +31,7 @@ }, "variables": { "_solutionName": "ESET Protect Platform", - "_solutionVersion": "3.0.0", + "_solutionVersion": "3.0.1", "solutionId": "eset.eset-protect-platform-solution", "_solutionId": "[variables('solutionId')]", "uiConfigId1": "ESETProtectPlatform", @@ -43,6 +43,13 @@ "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]", "dataConnectorVersion1": "1.0.0", "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]", + "parserObject1": { + "_parserName1": "[concat(parameters('workspace'),'/','ESETProtectPlatform')]", + "_parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'ESETProtectPlatform')]", + "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('ESETProtectPlatform-Parser')))]", + "parserVersion1": "1.0.0", + "parserContentId1": "ESETProtectPlatform-Parser" + }, "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" }, "resources": [ @@ -55,7 +62,7 @@ "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" ], "properties": { - "description": "ESET Protect Platform data connector with template version 3.0.0", + "description": "ESET Protect Platform data connector with template version 3.0.1", "mainTemplate": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "[variables('dataConnectorVersion1')]", @@ -152,7 +159,7 @@ "title": "Step 1 - Create an API user" }, { - "description": "Create a Microsoft Entra ID registered application by following the steps in the [Register a new application instruction.](https://learn.microsoft.com/en-us/azure/healthcare-apis/register-application#register-a-new-application)", + "description": "Create a Microsoft Entra ID registered application by following the steps in the [Register a new application instruction.](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)", "title": "Step 2 - Create a registered application" }, { @@ -321,7 +328,7 @@ "title": "Step 1 - Create an API user" }, { - "description": "Create a Microsoft Entra ID registered application by following the steps in the [Register a new application instruction.](https://learn.microsoft.com/en-us/azure/healthcare-apis/register-application#register-a-new-application)", + "description": "Create a Microsoft Entra ID registered application by following the steps in the [Register a new application instruction.](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)", "title": "Step 2 - Create a registered application" }, { @@ -333,17 +340,147 @@ } } }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('parserObject1').parserTemplateSpecName1]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "ESETProtectPlatform Data Parser with template version 3.0.1", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('parserObject1').parserVersion1]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[variables('parserObject1')._parserName1]", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Parser for ESET Protect Platform", + "category": "Microsoft Sentinel Parser", + "functionAlias": "ESETProtectPlatform", + "query": "IntegrationTable_CL\n | extend \n EventResult = \"NA\",\n EventProduct = \"ESET Connect\",\n EventVendor = \"ESET\",\n DvcIdType = \"Computer\",\n EventEndTime = column_ifexists('TimeGenerated', ''),\n SrcIpAddr = tostring(networkCommunication['localIpAddress']),\n DstIpAddr = networkCommunication['remoteIpAddress'],\n SrcPortNumber = toint(networkCommunication['localPort']),\n DstPortNumber = networkCommunication['remotePort'],\n NetworkDirection = case(\n networkCommunication['direction'] == \"NETWORK_COMMUNICATION_DIRECTION_UNSPECIFIED\", \"NA\",\n networkCommunication['direction'] == \"NETWORK_COMMUNICATION_DIRECTION_INBOUND\", \"Inbound\",\n \"Outbound\"\n ),\n NetworkProtocol = networkCommunication['protocolName'],\n EventStartTime = todatetime(occurTime), \n EventSeverity = case(\n severityLevel == \"SEVERITY_LEVEL_UNSPECIFIED\", \"Informational\",\n severityLevel == \"SEVERITY_LEVEL_LOW\", \"Low\",\n severityLevel == \"SEVERITY_LEVEL_MEDIUM\", \"Medium\",\n severityLevel == \"SEVERITY_LEVEL_HIGH\", \"High\",\n \"Unknown\"\n )\n | project-rename\n EventMessage = displayName,\n EventOriginalUid = detectionUuid,\n EventCount= groupSize, \n EventOriginalSeverity = severityScore,\n EventOriginalType = category, \n EventType = typeName, \n DvcDescription = deviceDisplayName, \n DvcId = deviceUuid, \n ActorUsername = userNameBase, \n TargetProcessCurrentDirectory = processPath, \n TargetProcessGuid = processUuid,\n TargetProcessCommandLine = processCommandline,\n TargetProcessFileSize = objectSizeBytes\n | extend \n Dvc = DvcId,\n User = ActorUsername\n | project-away\n severityLevel, networkCommunication, occurTime\n", + "functionParameters": "", + "version": 2, + "tags": [ + { + "name": "description", + "value": "" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]", + "dependsOn": [ + "[variables('parserObject1')._parserId1]" + ], + "properties": { + "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'ESETProtectPlatform')]", + "contentId": "[variables('parserObject1').parserContentId1]", + "kind": "Parser", + "version": "[variables('parserObject1').parserVersion1]", + "source": { + "name": "ESET Protect Platform", + "kind": "Solution", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "ESET" + }, + "support": { + "name": "ESET Enterprise Integrations", + "email": "eset-enterpise-integration@eset.com", + "tier": "Partner", + "link": "https://help.eset.com/eset_connect/en-US/integrations.html" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('parserObject1').parserContentId1]", + "contentKind": "Parser", + "displayName": "Parser for ESET Protect Platform", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '1.0.0')))]", + "version": "[variables('parserObject1').parserVersion1]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2022-10-01", + "name": "[variables('parserObject1')._parserName1]", + "location": "[parameters('workspace-location')]", + "properties": { + "eTag": "*", + "displayName": "Parser for ESET Protect Platform", + "category": "Microsoft Sentinel Parser", + "functionAlias": "ESETProtectPlatform", + "query": "IntegrationTable_CL\n | extend \n EventResult = \"NA\",\n EventProduct = \"ESET Connect\",\n EventVendor = \"ESET\",\n DvcIdType = \"Computer\",\n EventEndTime = column_ifexists('TimeGenerated', ''),\n SrcIpAddr = tostring(networkCommunication['localIpAddress']),\n DstIpAddr = networkCommunication['remoteIpAddress'],\n SrcPortNumber = toint(networkCommunication['localPort']),\n DstPortNumber = networkCommunication['remotePort'],\n NetworkDirection = case(\n networkCommunication['direction'] == \"NETWORK_COMMUNICATION_DIRECTION_UNSPECIFIED\", \"NA\",\n networkCommunication['direction'] == \"NETWORK_COMMUNICATION_DIRECTION_INBOUND\", \"Inbound\",\n \"Outbound\"\n ),\n NetworkProtocol = networkCommunication['protocolName'],\n EventStartTime = todatetime(occurTime), \n EventSeverity = case(\n severityLevel == \"SEVERITY_LEVEL_UNSPECIFIED\", \"Informational\",\n severityLevel == \"SEVERITY_LEVEL_LOW\", \"Low\",\n severityLevel == \"SEVERITY_LEVEL_MEDIUM\", \"Medium\",\n severityLevel == \"SEVERITY_LEVEL_HIGH\", \"High\",\n \"Unknown\"\n )\n | project-rename\n EventMessage = displayName,\n EventOriginalUid = detectionUuid,\n EventCount= groupSize, \n EventOriginalSeverity = severityScore,\n EventOriginalType = category, \n EventType = typeName, \n DvcDescription = deviceDisplayName, \n DvcId = deviceUuid, \n ActorUsername = userNameBase, \n TargetProcessCurrentDirectory = processPath, \n TargetProcessGuid = processUuid,\n TargetProcessCommandLine = processCommandline,\n TargetProcessFileSize = objectSizeBytes\n | extend \n Dvc = DvcId,\n User = ActorUsername\n | project-away\n severityLevel, networkCommunication, occurTime\n", + "functionParameters": "", + "version": 2, + "tags": [ + { + "name": "description", + "value": "" + } + ] + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "location": "[parameters('workspace-location')]", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Parser-', last(split(variables('parserObject1')._parserId1,'/'))))]", + "dependsOn": [ + "[variables('parserObject1')._parserId1]" + ], + "properties": { + "parentId": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'ESETProtectPlatform')]", + "contentId": "[variables('parserObject1').parserContentId1]", + "kind": "Parser", + "version": "[variables('parserObject1').parserVersion1]", + "source": { + "kind": "Solution", + "name": "ESET Protect Platform", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "ESET" + }, + "support": { + "name": "ESET Enterprise Integrations", + "email": "eset-enterpise-integration@eset.com", + "tier": "Partner", + "link": "https://help.eset.com/eset_connect/en-US/integrations.html" + } + } + }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", "apiVersion": "2023-04-01-preview", "location": "[parameters('workspace-location')]", "properties": { - "version": "3.0.0", + "version": "3.0.1", "kind": "Solution", "contentSchemaVersion": "3.0.0", "displayName": "ESET Protect Platform", "publisherDisplayName": "ESET Enterprise Integrations", - "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

ESET Protect Platform solution for Microsoft Sentinel ingests detections from ESET Protect Platform using the provided Integration REST API.

\n

Underlying Microsoft Technologies used:

\n

The ESET Protect Platform solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:

\n
    \n
  1. Logs Ingestion API in Azure Monitor

    \n
  2. \n
  3. Azure Functions

    \n
  4. \n
\n

Data Connectors: 1

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

ESET Protect Platform solution for Microsoft Sentinel ingests detections from ESET Protect Platform using the provided Integration REST API.

\n

Underlying Microsoft Technologies used:

\n

The ESET Protect Platform solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:

\n
    \n
  1. Logs Ingestion API in Azure Monitor

    \n
  2. \n
  3. Azure Functions

    \n
  4. \n
\n

Data Connectors: 1, Parsers: 1

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -371,11 +508,16 @@ "kind": "DataConnector", "contentId": "[variables('_dataConnectorContentId1')]", "version": "[variables('dataConnectorVersion1')]" + }, + { + "kind": "Parser", + "contentId": "[variables('parserObject1').parserContentId1]", + "version": "[variables('parserObject1').parserVersion1]" } ] }, - "firstPublishDate": "2024-10-15", - "lastPublishDate": "2024-10-15", + "firstPublishDate": "2024-10-29", + "lastPublishDate": "2024-11-08", "providers": [ "ESET Enterprise Integrations" ], diff --git a/Solutions/ESET Protect Platform/Parsers/ESETProtectPlatform.yaml b/Solutions/ESET Protect Platform/Parsers/ESETProtectPlatform.yaml new file mode 100644 index 00000000000..ae62738c90e --- /dev/null +++ b/Solutions/ESET Protect Platform/Parsers/ESETProtectPlatform.yaml @@ -0,0 +1,53 @@ +Function: + Title: Parser for ESET Protect Platform + Version: '1.0.0' + LastUpdated: '2024-11-08' +Category: Microsoft Sentinel Parser +Description: "" +FunctionName: ESETProtectPlatform +FunctionAlias: ESETProtectPlatform +FunctionQuery: | + IntegrationTable_CL + | extend + EventResult = "NA", + EventProduct = "ESET Connect", + EventVendor = "ESET", + DvcIdType = "Computer", + EventEndTime = column_ifexists('TimeGenerated', ''), + SrcIpAddr = tostring(networkCommunication['localIpAddress']), + DstIpAddr = networkCommunication['remoteIpAddress'], + SrcPortNumber = toint(networkCommunication['localPort']), + DstPortNumber = networkCommunication['remotePort'], + NetworkDirection = case( + networkCommunication['direction'] == "NETWORK_COMMUNICATION_DIRECTION_UNSPECIFIED", "NA", + networkCommunication['direction'] == "NETWORK_COMMUNICATION_DIRECTION_INBOUND", "Inbound", + "Outbound" + ), + NetworkProtocol = networkCommunication['protocolName'], + EventStartTime = todatetime(occurTime), + EventSeverity = case( + severityLevel == "SEVERITY_LEVEL_UNSPECIFIED", "Informational", + severityLevel == "SEVERITY_LEVEL_LOW", "Low", + severityLevel == "SEVERITY_LEVEL_MEDIUM", "Medium", + severityLevel == "SEVERITY_LEVEL_HIGH", "High", + "Unknown" + ) + | project-rename + EventMessage = displayName, + EventOriginalUid = detectionUuid, + EventCount= groupSize, + EventOriginalSeverity = severityScore, + EventOriginalType = category, + EventType = typeName, + DvcDescription = deviceDisplayName, + DvcId = deviceUuid, + ActorUsername = userNameBase, + TargetProcessCurrentDirectory = processPath, + TargetProcessGuid = processUuid, + TargetProcessCommandLine = processCommandline, + TargetProcessFileSize = objectSizeBytes + | extend + Dvc = DvcId, + User = ActorUsername + | project-away + severityLevel, networkCommunication, occurTime diff --git a/Solutions/ESET Protect Platform/SolutionMetadata.json b/Solutions/ESET Protect Platform/SolutionMetadata.json index 5e41a55f8d0..611c7dae729 100644 --- a/Solutions/ESET Protect Platform/SolutionMetadata.json +++ b/Solutions/ESET Protect Platform/SolutionMetadata.json @@ -1,8 +1,8 @@ { "publisherId": "eset", "offerId": "eset-protect-platform-solution", - "firstPublishDate": "2024-10-15", - "lastPublishDate": "2024-10-15", + "firstPublishDate": "2024-10-29", + "lastPublishDate": "2024-11-08", "providers": ["ESET Enterprise Integrations"], "categories": { "domains" : ["Security - Automation (SOAR)", "Security - Threat Protection"] From 167646c27976740bcb0f758986aa1cc6737c8f45 Mon Sep 17 00:00:00 2001 From: eset-enterpise-integration Date: Tue, 19 Nov 2024 10:56:43 +0100 Subject: [PATCH 2/3] Add id to ESETProtectPlatform.yaml. --- Solutions/ESET Protect Platform/Parsers/ESETProtectPlatform.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Solutions/ESET Protect Platform/Parsers/ESETProtectPlatform.yaml b/Solutions/ESET Protect Platform/Parsers/ESETProtectPlatform.yaml index ae62738c90e..4bd653d847a 100644 --- a/Solutions/ESET Protect Platform/Parsers/ESETProtectPlatform.yaml +++ b/Solutions/ESET Protect Platform/Parsers/ESETProtectPlatform.yaml @@ -1,3 +1,4 @@ +id: 'b0f36d45-4e08-4764-9200-4c5f7d706bb2' Function: Title: Parser for ESET Protect Platform Version: '1.0.0' From e29f7e2977d39ff2f24e108440f0131527715bc8 Mon Sep 17 00:00:00 2001 From: eset-enterpise-integration Date: Fri, 22 Nov 2024 13:54:00 +0100 Subject: [PATCH 3/3] Revert 3.0.1 to 3.0.0. Function code refactor. --- .../FunctionAppESETProtectPlatform.zip | Bin 11780729 -> 11780749 bytes .../Data Connectors/integration/main.py | 9 +-- .../Data Connectors/integration/utils.py | 57 +++++++++--------- .../ESET Protect Platform/Package/3.0.0.zip | Bin 7399 -> 7520 bytes .../ESET Protect Platform/Package/3.0.1.zip | Bin 7402 -> 0 bytes .../Package/mainTemplate.json | 8 +-- 6 files changed, 36 insertions(+), 38 deletions(-) delete mode 100644 Solutions/ESET Protect Platform/Package/3.0.1.zip diff --git a/Solutions/ESET Protect Platform/Data Connectors/FunctionAppESETProtectPlatform.zip b/Solutions/ESET Protect Platform/Data Connectors/FunctionAppESETProtectPlatform.zip index 142211ad90ff9cb38579ca95404f53886b3e1267..f0760ad2a6179d5ee4b9a2b72c0e63581de19084 100644 GIT binary patch delta 7176 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 NpMgU94;ud2{Xac{YcT)- diff --git a/Solutions/ESET Protect Platform/Data Connectors/integration/main.py b/Solutions/ESET Protect Platform/Data Connectors/integration/main.py index 821f61282e1..c837f792a77 100644 --- a/Solutions/ESET Protect Platform/Data Connectors/integration/main.py +++ b/Solutions/ESET Protect Platform/Data Connectors/integration/main.py @@ -23,14 +23,14 @@ def __init__(self) -> None: self.token_provider = TokenProvider(TokenStorage(), self.request_sender, self.env_vars, self.config.buffer) self.transformer_detections = TransformerDetections(self.env_vars) self._session: ClientSession | None = None - self.lock = asyncio.Lock() + self._lock = asyncio.Lock() async def close(self) -> None: if self._session and not self._session.closed: await self._session.close() async def run(self) -> None: - self._session = ClientSession() + self._session = ClientSession(raise_for_status=True) start_time = time.time() try: await asyncio.gather( @@ -108,7 +108,8 @@ async def _call_service( if not self.token_provider.token.access_token or datetime.now(timezone.utc) > self.token_provider.token.expiration_time: # type: ignore assert self._session - await self.token_provider.get_token(self._session, self.lock) + async with self._lock: + await self.token_provider.get_token(self._session) try: if ( @@ -117,7 +118,7 @@ async def _call_service( ): data = await self.request_sender.send_request( self.request_sender.send_request_get, - self._session, # type: ignore + self._session, # type: ignore { "Authorization": f"Bearer {self.token_provider.token.access_token}", "Content-Type": "application/json", diff --git a/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py b/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py index b62801d1e88..605c295219b 100644 --- a/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py +++ b/Solutions/ESET Protect Platform/Data Connectors/integration/utils.py @@ -73,7 +73,6 @@ async def send_request_post( data=urllib.parse.quote(f"grant_type={grant_type}", safe="=&/"), timeout=self.config.requests_timeout, ) as response: - response.raise_for_status() return await response.json() async def send_request_get( @@ -92,7 +91,6 @@ async def send_request_get( headers=headers, params=self._prepare_get_request_params(last_detection_time, next_page_token, page_size), ) as response: - response.raise_for_status() return await response.json() def _prepare_get_request_params( @@ -133,38 +131,37 @@ def get_token_params_from_storage(self) -> None: value = "" setattr(self.token, token_param, value) - async def get_token(self, session: ClientSession, lock: asyncio.Lock) -> None: - async with lock: + async def get_token(self, session: ClientSession) -> None: - if not self.token.access_token or datetime.now(timezone.utc) > self.token.expiration_time: # type: ignore - logging.info(f"Getting token") + if not self.token.access_token or datetime.now(timezone.utc) > self.token.expiration_time: # type: ignore + logging.info("Getting token") - if not self.token.access_token and (not self.env_vars.username or not self.env_vars.password): - raise MissingCredentialsException() + if not self.token.access_token and (not self.env_vars.username or not self.env_vars.password): + raise MissingCredentialsException() - grant_type = ( - f"refresh_token&refresh_token={self.token.refresh_token}" - if self.token.access_token - else f"password&username={self.env_vars.username}&password={self.env_vars.password}" - ) + grant_type = ( + f"refresh_token&refresh_token={self.token.refresh_token}" + if self.token.access_token + else f"password&username={self.env_vars.username}&password={self.env_vars.password}" + ) - try: - response = await self.requests_sender.send_request( - self.requests_sender.send_request_post, - session, - {"Content-type": "application/x-www-form-urlencoded", "3rd-integration": "MS-Sentinel"}, - grant_type, - ) - except AuthenticationException as e: - if not self.token.access_token: - raise InvalidCredentialsException(e) - else: - self.storage_table_handler.input_entity({k: "" for k in self.token.to_dict()}) # type: ignore[call-arg] - raise TokenRefreshException(e) - - if response: - self.set_token_params_locally_and_in_storage(response) - logging.info("Token obtained successfully") + try: + response = await self.requests_sender.send_request( + self.requests_sender.send_request_post, + session, + {"Content-type": "application/x-www-form-urlencoded", "3rd-integration": "MS-Sentinel"}, + grant_type, + ) + except AuthenticationException as e: + if not self.token.access_token: + raise InvalidCredentialsException(e) + else: + self.storage_table_handler.input_entity({k: "" for k in self.token.to_dict()}) # type: ignore[call-arg] + raise TokenRefreshException(e) + + if response: + self.set_token_params_locally_and_in_storage(response) + logging.info("Token obtained successfully") def set_token_params_locally_and_in_storage(self, response: t.Dict[str, str | int]) -> None: self.token.access_token = t.cast(str, response["access_token"]) diff --git a/Solutions/ESET Protect Platform/Package/3.0.0.zip b/Solutions/ESET Protect Platform/Package/3.0.0.zip index eeb260d163db65cd267ea3a6bf584b2b15a307d8..1fe8891fcd64e3b793cbb0e0d617da820dbd138b 100644 GIT binary patch literal 7520 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 literal 7399 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 I(SL6L0XrW)l>h($ diff --git a/Solutions/ESET Protect Platform/Package/3.0.1.zip b/Solutions/ESET Protect Platform/Package/3.0.1.zip deleted file mode 100644 index 6dca74df90f545600baff5e22bb1e076a1ef09eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7402 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