From 126ea95dad14937674fd48fe876862f56e7698e3 Mon Sep 17 00:00:00 2001 From: Ido Shabi Date: Thu, 23 Jan 2025 10:46:17 +0200 Subject: [PATCH] adding solution for Jamf Push connector --- .../Data Connectors/JamfProtect_ccp/DCR.json | 277 +++ .../JamfProtect_ccp/connectorDefinition.json | 208 ++ .../JamfProtect_ccp/dataConnector.json | 25 + .../JamfProtect_ccp/solutionMetadata.json | 11 + .../JamfProtect_ccp/table.json | 236 ++ .../JamfProtect_ccp/table2.json | 263 +++ .../JamfProtect_ccp/table3.json | 99 + .../JamfProtect_ccp/table4.json | 115 + .../Data/Solution_JamfProtect.json | 5 +- Solutions/Jamf Protect/Package/3.1.1.zip | Bin 42313 -> 51388 bytes .../Package/createUiDefinition.json | 6 +- .../Jamf Protect/Package/mainTemplate.json | 1988 +++++++++++++++-- .../Jamf Protect/Package/testParameters.json | 14 + .../Jamf Protect/Parsers/JamfProtect.yaml | 1654 +++++++------- 14 files changed, 3915 insertions(+), 986 deletions(-) create mode 100644 Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/DCR.json create mode 100644 Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/connectorDefinition.json create mode 100644 Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/dataConnector.json create mode 100644 Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/solutionMetadata.json create mode 100644 Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table.json create mode 100644 Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table2.json create mode 100644 Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table3.json create mode 100644 Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table4.json diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/DCR.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/DCR.json new file mode 100644 index 00000000000..b8ed113ca42 --- /dev/null +++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/DCR.json @@ -0,0 +1,277 @@ +{ + "name": "JamfProtectCustomDCR", + "apiVersion": "2021-09-01-preview", + "type": "Microsoft.Insights/dataCollectionRules", + "location": "[parameters('workspace-location')]", + "properties": { + "streamDeclarations": { + "Custom-jamfprotecttelemetryv2": { + "columns": [ + { + "name": "action", + "type": "dynamic" + }, + { + "name": "action_type", + "type": "int" + }, + { + "name": "deadline", + "type": "int" + }, + { + "name": "event", + "type": "dynamic" + }, + { + "name": "event_type", + "type": "int" + }, + { + "name": "glob_seq_num", + "type": "int" + }, + { + "name": "host", + "type": "dynamic" + }, + { + "name": "mach_time", + "type": "long" + }, + { + "name": "metadata", + "type": "dynamic" + }, + { + "name": "process", + "type": "dynamic" + }, + { + "name": "seq_num", + "type": "int" + }, + { + "name": "thread", + "type": "dynamic" + }, + { + "name": "time", + "type": "datetime" + }, + { + "name": "uuid", + "type": "string" + }, + { + "name": "version", + "type": "int" + } + ] + }, + "Custom-jamfprotectunifiedlogs": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "caid", + "type": "string" + }, + { + "name": "certid", + "type": "string" + }, + { + "name": "input", + "type": "dynamic" + } + ] + }, + "Custom-jamfprotecttelemetryv1": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "arguments", + "type": "dynamic" + }, + { + "name": "exec_chain", + "type": "dynamic" + }, + { + "name": "header", + "type": "dynamic" + }, + { + "name": "host_info", + "type": "dynamic" + }, + { + "name": "key", + "type": "string" + }, + { + "name": "return", + "type": "dynamic" + }, + { + "name": "subject", + "type": "dynamic" + }, + { + "name": "identity", + "type": "dynamic" + }, + { + "name": "texts", + "type": "string" + }, + { + "name": "metrics", + "type": "dynamic" + }, + { + "name": "page_info", + "type": "dynamic" + }, + { + "name": "attributes", + "type": "dynamic" + }, + { + "name": "exec_chain_child", + "type": "dynamic" + }, + { + "name": "path", + "type": "dynamic" + }, + { + "name": "_event_score", + "type": "int" + }, + { + "name": "contents", + "type": "string" + }, + { + "name": "file", + "type": "dynamic" + }, + { + "name": "socket_inet", + "type": "dynamic" + }, + { + "name": "exit", + "type": "dynamic" + }, + { + "name": "exec_args", + "type": "dynamic" + }, + { + "name": "exec_env", + "type": "dynamic" + }, + { + "name": "exec_chain_parent", + "type": "dynamic" + }, + { + "name": "architecture", + "type": "string" + }, + { + "name": "bios_firmware_versions", + "type": "dynamic" + }, + { + "name": "process", + "type": "dynamic" + }, + { + "name": "rateLimitingSeconds", + "type": "int" + } + ] + }, + "Custom-jamfprotectalerts": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "caid", + "type": "string" + }, + { + "name": "certid", + "type": "string" + }, + { + "name": "input", + "type": "dynamic" + } + ] + } + }, + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "[variables('workspaceResourceId')]", + "name": "clv2ws1" + } + ] + }, + "dataFlows": [ + { + "streams": [ + "Custom-jamfprotecttelemetryv2" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = metadata.vendor,\n EventProduct = metadata.product,\n EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = host.protectVersion,\n EventSeverity = \"Informational\",\n //\n // Jamf Protect - Device Hostnames\n TargetHostname = host.hostname,\n DvcHostname = host.hostname,\n DvcSerial = host.serial,\n DvcIpAddr = host.ips,\n DvcId = host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = host.os,\n SrcDeviceType = \"Computer\"\n| project-rename\n TimeGenerated = ['time'],\n EventOriginalUid = uuid,\n EventOriginalType = event_type,\n EventCount = glob_seq_num\n| project-away\n metadata,\n host,\n seq_num,\n version,\n deadline,\n mach_time,\n action_type\n\n", + "outputStream": "Custom-jamfprotecttelemetryv2_CL" + }, + { + "streams": [ + "Custom-jamfprotectunifiedlogs" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = \"Jamf\",\n EventProduct = \"Unified Log Stream\",\n // EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = input.host.protectVersion,\n EventSeverity = case(input.match.severity == 0, \"Informational\", input.match.severity == 1, \"Low\", input.match.severity == 2, \"Medium\", input.match.severity == 3, \"High\", \"Informational\"),\n EventOriginalType = input.eventType,\n EventOriginalUid = input.match.uuid,\n EventType = \"UnifiedLog\",\n EventResult = case(input.match.actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventMessage = input.match.event.name,\n EventResultMessage = input.match.event.composedMessage,\n // EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", input.match.uuid),\n // //\n // // Jamf Protect - Device Hostnames\n TargetHostname = input.host.hostname,\n DvcHostname = input.host.hostname,\n DvcSerial = input.host.serial,\n DvcIpAddr = input.host.ips,\n DvcId = input.host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = input.host.os,\n SrcDeviceType = \"Computer\",\n // Jamf Protect - Event Details\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = \"Create\",\n ProcessEventSubType = \"Exec\",\n TargetProcessName = tostring(input.match.event.process),\n TargetProcessId = toreal(input.match.event.processIdentifier),\n TargetProcessGuid = tostring(input.match.event.uuid),\n TargetProcessCommandLine = input.match.event.process.args,\n TargetProcessCurrentDirectory = input.match.event.processImagePath\n| project-away\n caid,\n certid\n\n", + "outputStream": "Custom-jamfprotectunifiedlogs_CL" + }, + { + "streams": [ + "Custom-jamfprotecttelemetryv1" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n// ASIM - Common Fields\n| extend EventVendor = 'Jamf'\n| extend EventProduct = 'Device Telemetry Stream'\n// Data Field Normalization\n| extend\n EventSeverity = \"Informational\",\n //\n // Jamf Protect Telemetry - Endpoint Information\n //\n TargetModel = metrics.hw_model,\n DvcOsVersion = host_info.osversion,\n TargetHostname = host_info.host_name,\n DvcHostname = host_info.host_name,\n DvcId = host_info.host_uuid,\n // Jamf Protect - Event Types\n EventType = case(\n header.event_name == \"AUE_add_to_group\",\n \"UserAddedToGroup\",\n header.event_name == \"AUE_AUDITCTL\",\n \"AuditEvent\",\n header.event_name == \"AUE_AUDITON_SPOLICY\",\n \"AuditEvent\",\n header.event_name == \"AUE_auth_user\",\n \"Elevate\",\n header.event_name == \"AUE_BIND\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_BIOS_FIRMWARE_VERSIONS\",\n \"SystemInformation\",\n header.event_name == \"AUE_CHDIR\",\n \"FolderMoved\",\n header.event_name == \"AUE_CHROOT\",\n \"FolderModified\",\n header.event_name == \"AUE_CONNECT\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_create_group\",\n \"GroupCreated\",\n header.event_name == \"AUE_create_user\",\n \"UserCreated\",\n header.event_name == \"AUE_delete_group\",\n \"GroupDeleted\",\n header.event_name == \"AUE_delete_user\",\n \"UserDeleted\",\n header.event_name == \"AUE_EXECVE\",\n \"ProcessCreated\",\n header.event_name == \"AUE_EXIT\",\n \"ProcessTerminated\",\n header.event_name == \"AUE_FORK\",\n \"ProcessCreated\",\n header.event_name == \"AUE_GETAUID\",\n \"\",\n header.event_name == \"AUE_KILL\",\n \"ProcessTerminated\",\n header.event_name == \"AUE_LISTEN\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_logout\",\n \"Logoff\",\n header.event_name == \"AUE_lw_login\",\n \"Logon\",\n header.event_name == \"AUE_MAC_SET_PROC\",\n \"AuditEvent\",\n header.event_name == \"AUE_modify_group\",\n \"GroupModified\",\n header.event_name == \"AUE_modify_password\",\n \"PasswordChanged\",\n header.event_name == \"AUE_modify_user\",\n \"UserModified\",\n header.event_name == \"AUE_MOUNT\",\n \"VolumeMount\",\n header.event_name == \"AUE_openssh\",\n \"SshInitiated\",\n header.event_name == \"AUE_PIDFORTASK\",\n \"ProcessCreated\",\n header.event_name == \"AUE_POSIX_SPAWN\",\n \"ProcessCreated\",\n header.event_name == \"AUE_remove_from_group\",\n \"UserRemovedFromGroup\",\n header.event_name == \"AUE_SESSION_CLOSE\",\n \"Logoff\",\n header.event_name == \"AUE_SESSION_END\",\n \"Logoff\",\n header.event_name == \"AUE_SESSION_START\",\n \"Logon\",\n header.event_name == \"AUE_SESSION_UPDATE\",\n \"\",\n header.event_name == \"AUE_SETPRIORITY\",\n \"\",\n header.event_name == \"AUE_SETSOCKOPT\",\n \"\",\n header.event_name == \"AUE_SETTIMEOFDAY\",\n \"SystemChange\",\n header.event_name == \"AUE_shutdown\",\n \"ShutdownInitiated\",\n header.event_name == \"AUE_SOCKETPAIR\",\n \"\",\n header.event_name == \"AUE_ssauthint\",\n \"Elevate\",\n header.event_name == \"AUE_ssauthmech\",\n \"Elevate\",\n header.event_name == \"AUE_ssauthorize\",\n \"Elevate\",\n header.event_name == \"AUE_TASKFORPID\",\n \"\",\n header.event_name == \"AUE_TASKNAMEFORPID\",\n \"\",\n header.event_name == \"AUE_UNMOUNT\",\n \"VolumeUnmount\",\n header.event_name == \"AUE_WAIT4\",\n \"ProcessTerminated\",\n header.event_name == \"PLAINTEXT_LOG_COLLECTION_EVENT\",\n \"LogFileCollected\",\n header.event_name == \"SYSTEM_PERFORMANCE_METRICS\",\n \"SystemPerformanceMetrics\",\n \"Unknown\"\n ),\n //\n // Jamf Protect Telemetry - Process\n //\n ActingProcessId = toreal(subject.responsible_process_id),\n ActingProcessName = tostring(subject.responsible_process_name),\n ParentProcessName = tostring(subject.parent_path),\n ParentProcessId = toreal(subject.parent_pid),\n ParentProcessGuid = tostring(subject.parent_uuid),\n TargetProcessName = tostring(subject.process_name),\n TargetProcessId = toreal(subject.process_id),\n TargetProcessGuid = tostring(exec_chain.uuid),\n TargetProcessSHA256 = tostring(subject.process_hash),\n TargetUserId = toreal(subject.user_id),\n TargetUsername = tostring(subject.user_name),\n TargetProcessCommandLine = exec_args.args_compiled,\n ActorUsername = tostring(subject.effective_user_name),\n ActorUserId = toreal(subject.audit_user_name),\n //\n // Jamf Protect Telemetry - Audit/Group\n //\n GroupName = tostring(subject.group_name),\n GroupID = toreal(subject.group_id),\n EffectiveGroupName = tostring(subject.effective_group_name),\n EffectiveGroupID = toreal(subject.effective_group_id),\n //\n // Jamf Protect Telemetry - Network\n //\n DstIpAddr = socket_inet.ip_address,\n DstPortNumber = socket_inet.port,\n NetworkProtocolVersion = case(socket_inet.id == 128, \"IPV4\", socket_inet.id == 129, \"IPV6\", \"\"),\n SrcIpAddr = subject.terminal.id.ip.address,\n //\n // Jamf Protect Telemetry - Binaries\n //\n TargetBinarySHA256 = tostring(identity.cd_hash),\n TargetbinarySignerType = case(identity.signer_type == 0, \"Developer\", identity.signer_type == 1, \"Apple\", \"\"),\n TargetBinarySigningTeamID = tostring(identity.team_id),\n TargetBinarySigningAppID = tostring(identity.signer_id),\n //\n // Jamf Protect Telemetry - Log File Collection\n //\n TargetFilePath = path\n| project-away _event_score\n\n", + "outputStream": "Custom-jamfprotecttelemetryv1_CL" + }, + { + "streams": [ + "Custom-jamfprotectalerts" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = \"Jamf\",\n EventProduct = \"Alerts Stream\",\n // EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = input.host.protectVersion,\n EventSeverity = case(input.match.severity == 0, \"Informational\", input.match.severity == 1, \"Low\", input.match.severity == 2, \"Medium\", input.match.severity == 3, \"High\", \"Informational\"),\n EventOriginalType = input.eventType,\n EventOriginalUid = input.match.uuid,\n EventType = case(\n input.eventType == \"GPClickEvent\",\n \"Click\",\n input.eventType == \"GPDownloadEvent\",\n \"Download\",\n input.eventType == \"GPFSEvent\",\n \"FileSystem\",\n input.eventType == \"GPProcessEvent\",\n \"Process\",\n input.eventType == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input.eventType == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input.eventType == \"GPMRTEvent\",\n \"MRT\",\n input.eventType == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input.eventType == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input.eventType == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input.eventType == \"GPUSBEvent\",\n \"USB\",\n input.eventType == \"auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventResult = case(input.match.actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventMessage = input.match.facts[0].name,\n EventResultMessage = input.match.facts[0].human,\n //\n // Jamf Protect - Device Hostnames\n //\n TargetHostname = input.host.hostname,\n DvcHostname = input.host.hostname,\n DvcSerial = input.host.serial,\n DvcIpAddr = input.host.ips,\n DvcId = input.host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = input.host.os,\n SrcDeviceType = \"Computer\",\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = case(input.match.event.type == 0, \"None\", input.match.event.type == 1, \"Create\", input.match.event.type == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input.match.event.subType == 7, \"Exec\", input.match.event.subType == 1, \"Fork\", input.match.event.subType == 23, \"Execve\", input.match.event.subType == 43190, \"Posix Spawn\", \"\"),\n ActingProcessName = tostring(input.related.processes[array_length(input.related.processes) - 1].path),\n ActingProcessId = toreal(input.related.processes[0].responsiblePID),\n ActingProcessGuid = tostring(input.related.processes[array_length(input.related.processes) - 1].uuid),\n ParentProcessName = todynamic(iff(array_length(input.related.processes) > 1, tostring(input.related.processes[1].path), \"\")),\n ParentProcessId = iff(array_length(input.related.processes) > 1, toreal(input.related.processes[1].pid), double(null)),\n ParentProcessGuid = tostring(iff(array_length(input.related.processes) > 1, tostring(input.related.processes[1].uuid), \"\")),\n TargetProcessName = todynamic(input.related.processes[0].name),\n TargetProcessId = input.related.processes[0].pid,\n TargetProcessGuid = input.related.processes[0].uuid,\n TargetProcessSHA1 = tostring(input.related.binaries[0].sha1hex),\n TargetProcessSHA256 = tostring(input.related.binaries[0].sha256hex),\n TargetProcessCommandLine = input.related.processes[0].args,\n TargetProcessCurrentDirectory = tostring(input.related.processes[0].path),\n TargetProcessStatusCode = toreal(input.related.processes[0].exitCode),\n //\n // Jamf Protect Alerts - Files\n //\n TargetFilePath = input.related.files[0].path,\n TargetFileSHA1 = input.related.files[0].sha1hex,\n TargetFileSHA256 = input.related.files[0].sha256hex,\n TargetFileSize = input.related.files[0].size,\n TargetFileSigningInfoMessage = input.related.files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(input.related.files[0].signingInfo.signerType == 0, \"Apple\", input.related.files[0].signingInfo.signerType == 1, \"App Store\", input.related.files[0].signingInfo.signerType == 2, \"Developer\", input.related.files[0].signingInfo.signerType == 3, \"Ad Hoc\", input.related.files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = input.related.files[0].signingInfo.teamid,\n TargetFileIsDownload = tobool(input.related.files[0].isDownload),\n TargetFileIsAppBundle = tobool(input.related.files[0].isAppBundle),\n TargetFileIsDirectory = tobool(input.related.files[0].isDirectory),\n TargetFileIsScreenshot = tobool(input.related.files[0].isScreenShot),\n TargetFileExtendedAttributes = input.related.files[0].xattrs,\n // Jamf Protect Alerts - Binaries\n TargetBinaryFilePath = input.related.binaries[0].path,\n TargetBinarySHA1 = input.related.binaries[0].sha1hex,\n TargetBinarySHA256 = input.related.binaries[0].sha256hex,\n TargetBinarySigningInfoMessage = input.related.binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(input.related.binaries[0].signingInfo.signerType == 0, \"Apple\", input.related.binaries[0].signingInfo.signerType == 1, \"App Store\", input.related.binaries[0].signingInfo.signerType == 2, \"Developer\", input.related.binaries[0].signingInfo.signerType == 3, \"Ad Hoc\", input.related.binaries[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetBinarySigningTeamID = input.related.binaries[0].signingInfo.teamid,\n TargetBinarySigningAppID = input.related.binaries[0].signingInfo.appid\n| project-away\n caid,\n certid\n", + "outputStream": "Custom-jamfprotectalerts_CL" + } + ], + "dataCollectionEndpointId": "[concat('/subscriptions/',parameters('subscription'),'/resourceGroups/',parameters('resourceGroupName'),'/providers/Microsoft.Insights/dataCollectionEndpoints/',parameters('workspace'))]" + } +} \ No newline at end of file diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/connectorDefinition.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/connectorDefinition.json new file mode 100644 index 00000000000..12b31926519 --- /dev/null +++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/connectorDefinition.json @@ -0,0 +1,208 @@ +{ + "name": "JamfProtectPush", + "apiVersion": "2022-09-01-preview", + "type": "Microsoft.SecurityInsights/dataConnectorDefinitions", + "location": "[parameters('workspace-location')]", + "kind": "Customizable", + "properties": { + "connectorUiConfig": { + "id": "JamfProtectPush", + "title": "Jamf Protect Push Connector", + "publisher": "Jamf", + "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.", + "graphQueries": [ + { + "metricName": "Telemetry", + "legend": "jamfprotecttelemetryv2_CL", + "baseQuery": "jamfprotecttelemetryv2_CL" + }, + { + "metricName": "Unified Logs", + "legend": "jamfprotectunifiedlogs_CL", + "baseQuery": "jamfprotectunifiedlogs_CL" + }, + { + "metricName": "Telemetry (Legacy)", + "legend": "jamfprotecttelemetryv1_CL", + "baseQuery": "jamfprotecttelemetryv1_CL" + }, + { + "metricName": "Alerts", + "legend": "jamfprotectalerts_CL", + "baseQuery": "jamfprotectalerts_CL" + } + ], + "sampleQueries": [ + { + "description": "Jamf Protect - All Alerts", + "query": "jamfprotectalerts_CL\n | sort by TimeGenerated desc" + }, + { + "description": "Jamf Protect - All Telemetry events", + "query": "jamfprotecttelemetry_CL\n | sort by TimeGenerated desc" + } + ], + "dataTypes": [ + { + "name": "jamfprotecttelemetryv2_CL", + "lastDataReceivedQuery": "jamfprotecttelemetryv2_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "jamfprotectunifiedlogs_CL", + "lastDataReceivedQuery": "jamfprotectunifiedlogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "jamfprotecttelemetryv1_CL", + "lastDataReceivedQuery": "jamfprotecttelemetryv1_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "jamfprotectalerts_CL", + "lastDataReceivedQuery": "jamfprotectalerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "IsConnectedQuery", + "value": [ + "jamfprotecttelemetryv2_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)", + "jamfprotectunifiedlogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)", + "jamfprotecttelemetryv1_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)", + "jamfprotectalerts_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)" + ] + } + ], + "availability": { + "status": 1 + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + } + ], + "customs": [ + { + "name": "Microsoft Entra", + "description": "Permission to create an app registration in Microsoft Entra ID. Typically requires Entra ID Application Developer role or higher." + }, + { + "name": "Microsoft Azure", + "description": "Permission to assign Monitoring Metrics Publisher role on data collection rule (DCR). Typically requires Azure RBAC Owner or User Access Administrator role" + } + ] + }, + "instructionSteps": [ + { + "title": "1. Create ARM Resources and Provide the Required Permissions", + "description": "This connector reads data from the tables that Jamf Protect uses in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API.", + "instructions": [ + { + "type": "Markdown", + "parameters": { + "content": "#### Automated Configuration and Secure Data Ingestion with Entra Application \nClicking on \"Connect\" will trigger the creation of Log Analytics tables and a Data Collection Rule (DCR). \nIt will then create an Entra application, link the DCR to it, and set the entered secret in the application. This setup enables data to be sent securely to the DCR using an Entra token." + } + }, + { + "parameters": { + "label": "Deploy Jamf Protect connector resources", + "applicationDisplayName": "Jamf Protect Connector Application" + }, + "type": "DeployPushConnectorButton" + } + ] + }, + { + "title": "2. Push your logs into the workspace", + "description": "Use the following parameters to configure the your machine to send the logs to the workspace.", + "instructions": [ + { + "parameters": { + "label": "Tenant ID (Directory ID)", + "fillWith": [ + "TenantId" + ] + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Entra Application ID", + "fillWith": [ + "ApplicationId" + ], + "placeholder": "Deploy push connector to get the Application ID" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Entra Application Secret", + "fillWith": [ + "ApplicationSecret" + ], + "placeholder": "Deploy push connector to get the Application Secret" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "DCE Uri", + "fillWith": [ + "DataCollectionEndpoint" + ], + "placeholder": "Deploy push connector to get the DCR Uri" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "DCR Immutable ID", + "fillWith": [ + "DataCollectionRuleId" + ], + "placeholder": "Deploy push connector to get the DCR ID" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Telemetry Stream ID", + "value": "Custom-jamfprotecttelemetryv1_CL" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Unified Logs Stream ID", + "value": "Custom-jamfprotectunifiedlogs_CL" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Telemetry (Legacy) Stream ID", + "value": "Custom-jamfprotecttelemetryv2_CL" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Alerts Stream ID", + "value": "Custom-jamfprotectalerts_CL" + }, + "type": "CopyableLabel" + } + ] + } + ] + } + } + } \ No newline at end of file diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/dataConnector.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/dataConnector.json new file mode 100644 index 00000000000..ae9f219ca93 --- /dev/null +++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/dataConnector.json @@ -0,0 +1,25 @@ +{ + "name": "JamfProtectPushConnectorPolling", + "apiVersion": "2023-02-01-preview", + "type": "Microsoft.SecurityInsights/dataConnectors", + "kind": "Push", + "properties": { + "connectorDefinitionName": "JamfProtectPush", + "dcrConfig": { + "streamName": "Custom-jamfprotecttelemetryv2", + "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + }, + "auth": { + "type": "Push", + "AppId": "[[parameters('auth').appId]", + "ServicePrincipalId": "[[parameters('auth').servicePrincipalId]" + }, + "request": {}, + "response": { + "eventsJsonPaths": [ + "$.messages" + ] + } + } +} \ No newline at end of file diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/solutionMetadata.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/solutionMetadata.json new file mode 100644 index 00000000000..6fca438aa2e --- /dev/null +++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/solutionMetadata.json @@ -0,0 +1,11 @@ +{ + "SolutionName":"Jamf Protect for Microsoft Sentinel", + "SolutionAuthor": "Thijs Xhaflaire", + "SolutionVersion":"3.2.0", + "PackageId": "azuresentinel.azure-sentinel-solution-JamfProtectPushV1", + "TemplateName": "JamfProtectPushV1", + "ConnectorDefinitionTemplateVersion": "1.0.0", + "DataConnectorsTemplateVersion": "1.0.0", + "PackageIcon":"JamfProtect", + "SolutionTier": "Partner" +} \ No newline at end of file diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table.json new file mode 100644 index 00000000000..eb812edc9c2 --- /dev/null +++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table.json @@ -0,0 +1,236 @@ +{ + "name": "jamfprotectalerts_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2021-03-01-privatepreview", + "tags": {}, + "properties": { + "plan": "Analytics", + "schema": { + "name": "jamfprotectalerts_CL", + "columns": [ + { + "name": "input", + "type": "dynamic" + }, + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "EventVendor", + "type": "string" + }, + { + "name": "EventProduct", + "type": "string" + }, + { + "name": "EventProductVersion", + "type": "dynamic" + }, + { + "name": "EventSeverity", + "type": "string" + }, + { + "name": "EventOriginalType", + "type": "dynamic" + }, + { + "name": "EventOriginalUid", + "type": "dynamic" + }, + { + "name": "EventType", + "type": "string" + }, + { + "name": "EventResult", + "type": "string" + }, + { + "name": "EventMessage", + "type": "dynamic" + }, + { + "name": "EventResultMessage", + "type": "dynamic" + }, + { + "name": "TargetHostname", + "type": "dynamic" + }, + { + "name": "DvcHostname", + "type": "dynamic" + }, + { + "name": "DvcSerial", + "type": "dynamic" + }, + { + "name": "DvcIpAddr", + "type": "dynamic" + }, + { + "name": "DvcId", + "type": "dynamic" + }, + { + "name": "DvcOs", + "type": "string" + }, + { + "name": "DvcOsVersion", + "type": "dynamic" + }, + { + "name": "SrcDeviceType", + "type": "string" + }, + { + "name": "ProcessEventType", + "type": "string" + }, + { + "name": "ProcessEventSubType", + "type": "string" + }, + { + "name": "ActingProcessName", + "type": "string" + }, + { + "name": "ActingProcessId", + "type": "real" + }, + { + "name": "ActingProcessGuid", + "type": "string" + }, + { + "name": "ParentProcessName", + "type": "dynamic" + }, + { + "name": "ParentProcessId", + "type": "real" + }, + { + "name": "ParentProcessGuid", + "type": "string" + }, + { + "name": "TargetProcessName", + "type": "dynamic" + }, + { + "name": "TargetProcessId", + "type": "dynamic" + }, + { + "name": "TargetProcessGuid", + "type": "dynamic" + }, + { + "name": "TargetProcessSHA1", + "type": "string" + }, + { + "name": "TargetProcessSHA256", + "type": "string" + }, + { + "name": "TargetProcessCommandLine", + "type": "dynamic" + }, + { + "name": "TargetProcessCurrentDirectory", + "type": "string" + }, + { + "name": "TargetProcessStatusCode", + "type": "real" + }, + { + "name": "TargetFilePath", + "type": "dynamic" + }, + { + "name": "TargetFileSHA1", + "type": "dynamic" + }, + { + "name": "TargetFileSHA256", + "type": "dynamic" + }, + { + "name": "TargetFileSize", + "type": "dynamic" + }, + { + "name": "TargetFileSigningInfoMessage", + "type": "dynamic" + }, + { + "name": "TargetFileSignerType", + "type": "string" + }, + { + "name": "TargetFileSigningTeamID", + "type": "dynamic" + }, + { + "name": "TargetFileIsDownload", + "type": "boolean" + }, + { + "name": "TargetFileIsAppBundle", + "type": "boolean" + }, + { + "name": "TargetFileIsDirectory", + "type": "boolean" + }, + { + "name": "TargetFileIsScreenshot", + "type": "boolean" + }, + { + "name": "TargetFileExtendedAttributes", + "type": "dynamic" + }, + { + "name": "TargetBinaryFilePath", + "type": "dynamic" + }, + { + "name": "TargetBinarySHA1", + "type": "dynamic" + }, + { + "name": "TargetBinarySHA256", + "type": "dynamic" + }, + { + "name": "TargetBinarySigningInfoMessage", + "type": "dynamic" + }, + { + "name": "TargetbinarySignerType", + "type": "string" + }, + { + "name": "TargetBinarySigningTeamID", + "type": "dynamic" + }, + { + "name": "TargetBinarySigningAppID", + "type": "dynamic" + } + ] + }, + "totalRetentionInDays": 30 + } + } + \ No newline at end of file diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table2.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table2.json new file mode 100644 index 00000000000..b3286c3b049 --- /dev/null +++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table2.json @@ -0,0 +1,263 @@ +{ + "name": "jamfprotecttelemetryv1_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2021-03-01-privatepreview", + "tags": {}, + "properties": { + "plan": "Analytics", + "schema": { + "name": "jamfprotecttelemetryv1_CL", + "columns": [ + { + "name": "architecture", + "type": "string" + }, + { + "name": "arguments", + "type": "dynamic" + }, + { + "name": "attributes", + "type": "dynamic" + }, + { + "name": "bios_firmware_versions", + "type": "dynamic" + }, + { + "name": "contents", + "type": "string" + }, + { + "name": "exec_args", + "type": "dynamic" + }, + { + "name": "exec_chain", + "type": "dynamic" + }, + { + "name": "exec_chain_child", + "type": "dynamic" + }, + { + "name": "exec_chain_parent", + "type": "dynamic" + }, + { + "name": "exec_env", + "type": "dynamic" + }, + { + "name": "exit", + "type": "dynamic" + }, + { + "name": "file", + "type": "dynamic" + }, + { + "name": "header", + "type": "dynamic" + }, + { + "name": "host_info", + "type": "dynamic" + }, + { + "name": "identity", + "type": "dynamic" + }, + { + "name": "key", + "type": "string" + }, + { + "name": "metrics", + "type": "dynamic" + }, + { + "name": "page_info", + "type": "dynamic" + }, + { + "name": "path", + "type": "dynamic" + }, + { + "name": "process", + "type": "dynamic" + }, + { + "name": "rateLimitingSeconds", + "type": "int" + }, + { + "name": "return", + "type": "dynamic" + }, + { + "name": "socket_inet", + "type": "dynamic" + }, + { + "name": "subject", + "type": "dynamic" + }, + { + "name": "texts", + "type": "string" + }, + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "EventVendor", + "type": "string" + }, + { + "name": "EventProduct", + "type": "string" + }, + { + "name": "EventSeverity", + "type": "string" + }, + { + "name": "TargetModel", + "type": "dynamic" + }, + { + "name": "DvcOsVersion", + "type": "dynamic" + }, + { + "name": "TargetHostname", + "type": "dynamic" + }, + { + "name": "DvcHostname", + "type": "dynamic" + }, + { + "name": "DvcId", + "type": "dynamic" + }, + { + "name": "EventType", + "type": "string" + }, + { + "name": "ActingProcessId", + "type": "dynamic" + }, + { + "name": "ActingProcessName", + "type": "dynamic" + }, + { + "name": "ParentProcessName", + "type": "dynamic" + }, + { + "name": "ParentProcessId", + "type": "dynamic" + }, + { + "name": "ParentProcessGuid", + "type": "dynamic" + }, + { + "name": "TargetProcessName", + "type": "dynamic" + }, + { + "name": "TargetProcessId", + "type": "dynamic" + }, + { + "name": "TargetProcessGuid", + "type": "dynamic" + }, + { + "name": "TargetProcessSHA256", + "type": "dynamic" + }, + { + "name": "TargetUserId", + "type": "dynamic" + }, + { + "name": "TargetUsername", + "type": "dynamic" + }, + { + "name": "TargetProcessCommandLine", + "type": "dynamic" + }, + { + "name": "ActorUsername", + "type": "dynamic" + }, + { + "name": "ActorUserId", + "type": "dynamic" + }, + { + "name": "GroupName", + "type": "dynamic" + }, + { + "name": "GroupID", + "type": "dynamic" + }, + { + "name": "EffectiveGroupName", + "type": "dynamic" + }, + { + "name": "EffectiveGroupID", + "type": "dynamic" + }, + { + "name": "DstIpAddr", + "type": "dynamic" + }, + { + "name": "DstPortNumber", + "type": "dynamic" + }, + { + "name": "NetworkProtocolVersion", + "type": "string" + }, + { + "name": "SrcIpAddr", + "type": "dynamic" + }, + { + "name": "TargetBinarySHA256", + "type": "dynamic" + }, + { + "name": "TargetbinarySignerType", + "type": "string" + }, + { + "name": "TargetBinarySigningTeamID", + "type": "string" + }, + { + "name": "TargetBinarySigningAppID", + "type": "string" + }, + { + "name": "TargetFilePath", + "type": "dynamic" + } + ] + }, + "totalRetentionInDays": 30 + } +} diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table3.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table3.json new file mode 100644 index 00000000000..f523f6ac233 --- /dev/null +++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table3.json @@ -0,0 +1,99 @@ +{ + "name": "jamfprotecttelemetryv2_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2021-03-01-privatepreview", + "tags": {}, + "properties": { + "plan": "Analytics", + "schema": { + "name": "jamfprotecttelemetryv2_CL", + "columns": [ + { + "name": "action", + "type": "dynamic" + }, + { + "name": "event", + "type": "dynamic" + }, + { + "name": "EventOriginalType", + "type": "int" + }, + { + "name": "EventCount", + "type": "int" + }, + { + "name": "process", + "type": "dynamic" + }, + { + "name": "thread", + "type": "dynamic" + }, + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "EventOriginalUid", + "type": "string" + }, + { + "name": "EventVendor", + "type": "dynamic" + }, + { + "name": "EventProduct", + "type": "dynamic" + }, + { + "name": "EventSchemaVersion", + "type": "dynamic" + }, + { + "name": "EventProductVersion", + "type": "dynamic" + }, + { + "name": "EventSeverity", + "type": "string" + }, + { + "name": "TargetHostname", + "type": "dynamic" + }, + { + "name": "DvcHostname", + "type": "dynamic" + }, + { + "name": "DvcSerial", + "type": "dynamic" + }, + { + "name": "DvcIpAddr", + "type": "dynamic" + }, + { + "name": "DvcId", + "type": "dynamic" + }, + { + "name": "DvcOs", + "type": "string" + }, + { + "name": "DvcOsVersion", + "type": "dynamic" + }, + { + "name": "SrcDeviceType", + "type": "string" + } + ] + }, + "totalRetentionInDays": 30 + } +} diff --git a/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table4.json b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table4.json new file mode 100644 index 00000000000..1bbe8388cdb --- /dev/null +++ b/Solutions/Jamf Protect/Data Connectors/JamfProtect_ccp/table4.json @@ -0,0 +1,115 @@ +{ + "name": "jamfprotectunifiedlogs_CL", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "apiVersion": "2021-03-01-privatepreview", + "tags": {}, + "properties": { + "plan": "Analytics", + "schema": { + "name": "jamfprotectunifiedlogs_CL", + "columns": [ + { + "name": "input", + "type": "dynamic" + }, + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "EventProductVersion", + "type": "dynamic" + }, + { + "name": "EventSeverity", + "type": "string" + }, + { + "name": "EventOriginalType", + "type": "dynamic" + }, + { + "name": "EventOriginalUid", + "type": "dynamic" + }, + { + "name": "EventType", + "type": "string" + }, + { + "name": "EventResult", + "type": "string" + }, + { + "name": "EventMessage", + "type": "dynamic" + }, + { + "name": "EventResultMessage", + "type": "dynamic" + }, + { + "name": "TargetHostname", + "type": "dynamic" + }, + { + "name": "DvcHostname", + "type": "dynamic" + }, + { + "name": "DvcSerial", + "type": "dynamic" + }, + { + "name": "DvcIpAddr", + "type": "dynamic" + }, + { + "name": "DvcId", + "type": "dynamic" + }, + { + "name": "DvcOs", + "type": "string" + }, + { + "name": "DvcOsVersion", + "type": "dynamic" + }, + { + "name": "SrcDeviceType", + "type": "string" + }, + { + "name": "ProcessEventType", + "type": "string" + }, + { + "name": "ProcessEventSubType", + "type": "string" + }, + { + "name": "TargetProcessName", + "type": "dynamic" + }, + { + "name": "TargetProcessId", + "type": "dynamic" + }, + { + "name": "TargetProcessGuid", + "type": "dynamic" + }, + { + "name": "TargetProcessCommandLine", + "type": "dynamic" + }, + { + "name": "TargetProcessCurrentDirectory", + "type": "dynamic" + } + ] + }, + "totalRetentionInDays": 30 + } +} diff --git a/Solutions/Jamf Protect/Data/Solution_JamfProtect.json b/Solutions/Jamf Protect/Data/Solution_JamfProtect.json index 67b25873a60..5eef4739d84 100644 --- a/Solutions/Jamf Protect/Data/Solution_JamfProtect.json +++ b/Solutions/Jamf Protect/Data/Solution_JamfProtect.json @@ -4,7 +4,8 @@ "Logo": "", "Description": "The [Jamf Protect](https://www.jamf.com/solutions/threat-prevention-remediation/) solution for Microsoft Sentinel enables you to ingest [Jamf Protect events](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html#task-4227) forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.", "Data Connectors": [ - "Data Connectors/JamfProtect.json" + "Data Connectors/JamfProtect.json", + "Data Connectors/JamfProtect_ccp/connectorDefinition.json" ], "Parsers": [ "Parsers/JamfProtect.yaml" @@ -32,7 +33,7 @@ "Playbooks/JamfProtect_Alert_Status_Resolved/azuredeploy.json", "Playbooks/JamfProtect_LockComputer_with_JamfPro/azuredeploy.json" ], - "BasePath": "/Users/thijs.xhaflaire/Documents/GitHub/Microsoft/Azure-Sentinel/Solutions/Jamf Protect", + "BasePath": "C:\\Github\\Azure-Sentinel\\Solutions\\Jamf Protect", "Version": "3.1.1", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, diff --git a/Solutions/Jamf Protect/Package/3.1.1.zip b/Solutions/Jamf Protect/Package/3.1.1.zip index dfab820c162a30fe2c414cd948a4d69d0ad51e79..76bc66d07a22099afef071599e24d3a6d18a982e 100644 GIT binary patch literal 51388 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

H_})gZGhlDghg8W| z>zfL#*Fk}uX`#|Xe>B26=_nXVf60+{g_J2GQl*sYstGq(*8akLs0s@@%ujin%(GR3 zVVgF(C|b60-vJ_qAyAPtWthVADIS|f)!LS(Sh(3D)ROIO=UF*e^*NyA11A{9KvN*t(kW8Lq* zP{vgCn4Q?@UrP3>9ZOSlI=3ij`hFiOZHt$BCT9vWA!s7vCBxo*S|n$SNm!vFN<&od z4U5M@OTG5i7RF~TIQgV(HmHE4hJ4PZc<_V{TN00RO*Q{|V`cK%6Y5}oTP_~C@Yd6# zo`-Tdby%_aAW@rq&Zs8R%KmthSP%M`bu*mDBaZQKJ3eN$X{*%bSH`Dyuuq%8a`BqF`B*t%x|;DlM|xB4jH7FPXyRX5Ipfq*TR}MCK?`RN^Jh-;z@BW-O7Lu9r=tn zoO}!FE7o9+fjQj>r|*;K5wlK@L^__AhH>-#uASk;(~_iSo~u?7 z?zlBTq&LXp&L&uEM>bU1*EIR1#o(NX6}p2_`!UrZXV0{KQX`O0+4T(IQ_m6*JviPl zhF;(cGox$>4RR4qJiAC=^5A@9#u2pCvaUG&)h$^YuZA>Zqd}J*EEUD1_2}7YT zA9~+h<{YV8=Sd2iO`5BHDlv9KR*Hu_9?o`*Jd~&Oa}_Z6L&uHTd-}Z>74bzQ@i)2> zeH$?nLPF}%NOX%<;)WH0apXuHdV3CAn%m567Kp?Z*Z@gRD;zz6v=NyoL7wfJsWWC$ zc?_n@$%Zx*xaTY9gs-BRnh2!w&XHODi5{Xp6RQ8Or`tO6<_xRdekPe-6ctS&{2n<3 zYPw&JL?qh~$(ortbE&SlZyJiZo^@Nf$&6n9WbS=qQs)ur&JvH9#Ux>}LqHho?1Xr% z8&rYXMc%IeinQVQ{{WRhYQGpkVw-ffgINxszLgPy%!J)qNTB>UM`{?{s$(0OCo^Iv zFIGkr=7YOYRDICtMoP;9h5;SlS<%68Cxh+CY52Xz04a;aNgEj&gBr%U!5%{;| zkpu|T7A4{7(3#WmYGn(f zpJQP#MN}j%NA5_F*`I|kYkIgiwd9R<)iID=lDu(ouM-F0Tz4(m*56-RUM$QSSdl^x z99rhJT1$W4g5c7Yq!R39y!l7)R!)TqbI)6(l{>Ncxxj;VT*@GG;vJ*<;ryChiRmW| z@6?pMRLq3tHTlmbQdLQEFA2TjkCL<(5l(L>Hs+4CbZit}3Lg-5;IPTe$TgBGqAr%0 zQqoyYK(JaKkC`r#SA(F(IwV<`^Ve&8THjwATe zLe*_T|B2L73nSSR;jA+m>GXc3C{y;9^;c)#NgaffGyTv4jfC@>=zTuD-0qdq%eeDe z*pqv1=Hl(@jC*`#_rr2A#zcvGFG5pGHB#09J)jG&kX%aeRdRX97IxCm=Kg5mQEVT4 z4pnr{(UNRUlCY4(S0X$rX)q(|gQxV9axtcV4nnTEhY1)M(>H~`x5~y(=C+?y8!kCN zh4Z%MZzA_GeqFkO8blYX4iK$7)zKkfSo#v) z>etcr%nA!7U^(9!pTVNA7rSX~>?>_;7+eLwJK>8}Bb!RGH1iLOWhF8LYp@C+Bjge! z=GzX)h`otifHsl;F^MEvL-GQ#eGJ=7P5{~5wC zBvwFVZL;F~l3d-fgyhnCq~Pt{0Ufo-Qy%F8OWY#T-f54AW4dKQ)Wigc2 z1MN7;D1xJx6i?7bF%+JE9kVl2ak}snoD-5@8<1Zt2ir=(bKL0xE=y$sbmO&*$ZPPN|-=`Y6&BX^HR<$R_>zeV$vh+T5D&}9oTKH zcQEX=?SpR5861pzs(R3~G)?V}ETeDq%Uo+MA7LS5U_`LcanMq(t6qOcB12L!)clBZ zTVPP6*$4SuM=>1=3NzBzfFSfo}we1&bV!0wY836 zX$S2=e|XRZ9y=I!JHvxszh{iQ!;YzTyJffyxQxn|GI0tVVcYOF(+ot+H9iB+}k9voHE44KnBNDLVcs1j<94e2w<5HrU<{wy+a#EVA%o zgVEUBf*K44eULH_OF>EIJ;s`&1D7mC++X2H|z%McO@;#fp4?usw%(_mtEHN46U*D{{fxq{7|G zgWe?d@bIN%XI<3|Ej{ap*9Zipav-nX%s#QrY|cIG1MF8<0^#+(^+B!c(|3nQ2mkpG z_1DYOKaNjp(>f1R<}$HUEbH2#^Ryj01)MkuuT7FU(oJFpr*GOMejavj@|r-=00xhW zqz-B{51^nU(j3ag;g++KH!Wni^M~v|?Nq!ANayPqP;xPPv zi+#r-$pC9MMAI&6PRy&_i5%nI1694U^}7 z`(=@oOtCT9;zf{aTVVOJhH~bN1dirl&9!g+Q(x4re?@pMHWrfW*`5yP(b7jCp{~7o zs$`6o%FlnXD|6z_Nba~&*16=WtmJ$iH(jkKHuvW%N$6m~a@l znp`H{y_+T>qc4xAKIw0GK8=AUI2@Q^Ny0S}-7d6J)b5Pdm3&Tm)MLH0$5G~HsoQz# zAgBpo1I=vrVwjzc!B{c|PnXqYMUMRiJygF2xAP_nvpTQ%D13c#_Tt!C=z0Rhm!jl& z(+u^vR1?vk8;*n74WAO0A0vMCUXm$<)Qu#2UsloV2miuhkDnxd@a2f>Wpekz^^9~7 z9#_#6X462C&`1ydlV|=BlFC1M6>`p}>jml%vG3_hgfUHV^?|+u2gd6XxM~7+#|eeK z(f8m^?a6__&&P&;Gxm%*jc54pK14*{8l?2iVlnf7Y_+ZdQdo|g;MQ-w<0IHQoXsXI zQ}e+I8^Qw|6;wuk3rxOo>lW}Yd)}f=lJUitO&a(4{m=QI)5iXP`~Q%;#6NsVHhxqZ zuo9(3__ua%vRuL>| z06slQTTKw8XJoda6+Acs;?t*v@mRe0w|1!Twcip4-p7|1I;w1?IAgIQP8F@U=(3!@es=C(f6jv9Pio=ps)GkmN6C zxE@#1lw`PM&YuSIzLm*CswhUHiAK(&AX`SuSG6;+pOwj4BQMZ7!=d~EW zarO#U&pHMsqm%Cm{E)_^f!R4wyHW!)G%SUl80_HY`Ep`YV*xtT6rb{sUd(J0=dmq} z5N3uU9gt2g>Ba#s5*b=1!Tb-?sN89MA^--R{F~M>7mEcgVg1=cNIW`;Io>Mx_cC#Jf zSx{e7K522~z;}tFCZbQ85LXTT#oV|}=c%R-}7I94VTROHzbDRk8J(fh(pY{BB4g#8^;Y;ErO2CjfeY47dd>@6X1? zZ--isoZt*jM(K#g$?uDVNGS$Rep0XYSe;AbI#Qm*OY4qdE_^7}T)^wFC`1RDLCicY zi3OA!!v|`DY^x+dKKe6JSUi=2rK7(S#m|t}VK+;UeIy?wDx3mu&5g-B?~aHwT1oOS zQ4!dZTu)+54#{N$v}WWff1Icb(ZZm&?6-FY1*NfO@>#NTbN3E5?br5OALKqyLYe*| z(EvYNgLT4xC%Z-yQy)$(maUrgjXpLakCT0KeG|rw9BhgIOcF%$=|@IT^61Y-z*-P% zGIe2D(Ug_uXWf`XX!S0zK3+1m`x>D0!-M}c4*miF-TKx=bXie_yY52@0JdU{vc(zY zS9)a`r}F~9^aV#};Wyf^&cypd^(%|DESW;i-+f{A_xV-XG_IJ7h**NlKQPNiDEKSsL z1h7imN~UZi8v!boz6Vtj`%8Jb&<=~$HaT^4Cm{%LX-ksL=apPx;AKYdjM)r9{h}QQ zXmDb!s+`dPX@uUW1Wl2RKI#FY_fq%YWH9h}3|Egr6m80=%29}-q|Ov6|a^`TtNn15m~;t-h$o|P}9dSueb z9h8Zw#H){|*Ow6ObCTvY;q-Ed4%-l~v0YJ(6xI3k1{sbrNgfBpg#?Gs?0H55e8_NU zblAV#q;PM(5qsxfrwkb;Nyr`mW_Rls!3Kjp$?bqdCS=@%Devd7gwvUr77m~%dI2_m z_1iZx=)$}2-!Y#YO=sp#?=TDv*gvfwq-6$*9L0nJd6-p?BRtWH5%4Fg`tdzj2(Ec1 zVs3?9cO+0N`0P0eY4|vo!fE2S*+=gKc>vn_bD9Hhe?6l9Aa^wvp@_z4(Cj7;L=?mJ z3R17cfnp>KT3VC@UV{+J)i80h04fCK-`Nln!4%}=E$VGtl4**4Zo@20 zk0u^~-2z!@NDQen0Z-!?fUzjh(~|-{G8j9j)v(f${$fMu0!JMBX42#6Ry(!8p|i>O zx~Qil>Me};1Xo5_s zaz-PS7bWp1rBq2$*lD~nLMcDdVf@jm$ffn$+<>5bE|E^!ibyA|j&#~|q!T+I!}2e^ z?1-m0`>~25*FD>aCoNTc$GiXRBc7yjPdmOMJCDo`A+i%E%@V;+(N-TT3QBs2Ux)qy$Hl#Q#(~dd2ar9laHE^a}i2gr;-AH!PQkf{TSc^Iw<;IwlWl|8wnseo6l4 zIK&9>+P3`9+M51n3F&M5pNpZ6595E%iTbi;YyWdN7PbGm_CG&THjMJ3WK;g<4BWni zBRY-xpb4$GBf4mt8<3dK#Sz_E;fU_kj_6H0qCZX%EV3{!+spPs$9a!c6j|=sdZ9b1 zLOkC6=jeqNT$ih|aIn>aX$&`;i$iGmA$`%o_2G?h-BSx)j_}psI}m$Nj+jnk9~%zTsC@ul9uMDqT|P~Q}Ft&A3qG7 zRi-gpfFX$Kh{^TsOQs|zDN3@s=L%oY5x$MME2Ml;pOvf6%Dn(zMSLR)o3L&9DmrWW zDkP+@?W-uZH+>jiMNVvhHCy{C!m+4*6}7LTGQNtuqGVIPiZoECgrg#j^q`4OaYseb zHa8$HpQfYY2I4zmZ%JY!!!v>6(>gc!gXadRqg??=O_16R(LihS_;rK&43j3+h zTdJOuuVOX(RV_!jY|Z+{oo!v%#vDe;&u6i>RT#qzOC7mG=j_4eUnc{iw;#pJU;}=G zt^bhM0}$#8!rkz{0e{QwW+B2@WcZX!D=S(@ z-!S_l%QRG@J2X1l(6KrLYtS`EeN(eL1Ffxg)UN3m{k~~hV|$>DwE@ZX%i8Li{lTC; za4e@iHhROMIUL)4ZQO5n2Ife!I^C`@u)0pSKi0aA(bIZ%&o+#XWp_I2xZO9!wt55A zvo}v4Ikq*`aE9Xn{L`_GfzuuKtnL8l>TA|W8?<{JOY543*&TFy)A(l2ZlofI>feM z$lH!#!APs7)9Lrrwqv*3stxO6*zJuqsO*fPgB=UTN*(k^Hf)6lW(Q`g+j9o0*p|_U zZuBj6WOj_cq4h?6V>E=3?W@DixNm9wq0a}~raa$etVCs6ns2vz@7(*Dov4xy7HdJQ_#CIcYIU~dBYQ|`6 z!9U>hLwhtDzzmuOu%_A@4v>rcMhC`c>^O#LX{uvG{|CrLoi6kdd}xZ|&4r6J$r^3I zifd}UUbEY63iQ&Vy90=^wKwKlvMY0b7Ke38lr zo=1?}=LYH$vwpWu-SOO*-?vVU<bcn@E57aM?-5;lOI$p ze)5m&g%#JUMWN7-z762A>nlW7;thEdewiLUU98M$)txsKi9HyMv=&hNN z-E`Ev&ym#Y5jtNG>nzlGHr6RJK@q64^wxqkTSJ}USkzEw4Rt;e)LCAV#G%eKL9)i? zRgQKt^|dfQ+q-GwwBJ)fp@34`x%n^n4{En1u`@1c)ER3dwK}OP_J}r8cHk%lJ8hg7 zRB}?p_1X0+dX+hFG|jymf049(IUYuq($ zL>2=?46sN8fHV^Tzp>${?Y5-?_Gkdq)mBaT0iQ9t{`0}8q_6Bx$)CL3?P(MIdJ0lG`W_LRPw{^9i)dpnL0LC!-HoWcumJOip za9{=KAz-aNz|uy5@%0hx>j0wN1=v?SsWZGT~Vi_%3FDGhE*{rlw7j{2^5)y%&o7Ht8*u&Bp)}gG){K-x)p*o?(F$ zdo(-|96o?2svY^ILp7FIX)IAo-Ii$E!V+^NXn2IquZ<;UG`=k?F{h2onysV&|!1i2;8)fahgfX1~qH_wO;w3{&aqeRkMW%b<5L5T5LQI^! z9|>W?Y;S)y)bYrG;54{oyx#Ec_qnaVI7%4`?OGd5MA@aeJI?T?0L#~JkzLTX#4 zJ=VI$h_&rlZPRvo#@O!Is;Lcn{Xu)w?i+2VWAuQ&cBeZWb=&I ziS-^063goR+K^aAz882}pjgJpJ!w#^ zbibZ0DAr#AiuG$y?14bB%jJAAv0pME7Uw-yQDnIn4v6)iDj-Ig`%%N3@bUzwYxK2F zZ#e9<9lO^V^bG@$uyNby^m@IqYK}T)yWj5tLZz9i*><|4ZeMfy?XHPw-k%ptL#L#M zXljV&g+Mg@RAaBdEr_Q7Xb??S=hud4G8*3&M3d8YV9nMLO*j@cL{mdFm4RsTN|Mb& zG)e39X~8oYqxPiXnbQ4ww(!hg1w1pT;h6`5XAT$Mt!rK^Y)nx5l2MvC3$ltL=e=;0 zX7E%|nh1|Sde$S;?wGxS-8WUOH)^*Hj0@_wjX}HbI33N=`lFH4u{*}FYmZfXJhq1; z&FER(@z5EM%z+^!8E>1WF&y^>9cu(}OJj(I8aNQU1Yc;w$lC*>V~m`kt*Q`i)NLD1 zXJ|pZQX2xJELC%a6zYS1e`uKo-ioO??S5y}w=k2q(Hp8`_{7NQ^ank_jLfz@az;aY zFtP?ct8ZgBh5#t>)ZpRuei4kSKUT+<-Gf*w)fqs)M?I@IFuQF$ZrAPix?KZ6E7i22 z3%xePc0m^$h_X_ucfXJn5)Kor78D3m^%5T_f zw$*+U5Bv4HnQ6)m!e%~Yv*!k@Mb=P_uGQ$;3qjWgskZuHTj<*0(a^Q5&aaKGWi-Am zbSCk|skC2~?HJ3+;t!4}aF+a`Iioe3*a|(q2J9&5@`fk* zEikQQ3;>;3kXz57BZ~bMn&Ol?ptJ}eBB%I!;bG&;ommcL*xH?*+SBXB4U}r{uN?Cn zGHC5#CGeT&kbyn*u3b|(oXuLit1HJy{Fw!p$A6)G!>T>jSeCm@jNoNdN_e6Q|QW_ zJWdzJUQS-P#fj`~<0~my@q0n7k%xzf+$F}bGx5IU;-SHTI#|U+;#%ZZ-NSPYh)9^% z#eE7}1Ui!3XL{(vTAtcgQqPp&I4}f=Sq-KFk}gkB2|CuDx~!ve#wcir%k%=BQNcuK zYd)CdkPMlLo?)t!U27Cg$!VI0{S)O?YB6E1=$>18mqpr58iDDopB!g?BX09V**3nL zNRbY5`>PoSi6z3#5W?nxe%`?OIfu*dqhnQ|Na*`@;by5hHJ(l+Z9JcQDbvDNa z3rpupLwBbpkuuk?%YeqdLDM$9qwaLJTx2c{C^Yu06d5NJGL6XuuXxs%^9d62 z`rE|y7f0;r$N6M;FS!p{J@2IL8_!>?CLrkcs-lAGcrEgWC@psOK1D6^ovTlR^$Dnp zOl1oFDcRMTLAFed7N7M4;MVlZeKI~(gfWd(BC_#|H`i^$yvbxj*t)Yajn|CV-vICI z?)}@R9gj%Xoh$ffsNTp=vfqP$X0Yi>`ba5=c>uHK7L}I1@Pc)t@BY!*Tgg82<@C@2 zKFGm5zg=FQ>1Q77F*MFTGvzvcE)d9)S-%hQW=aLmI z4UmX@?P6&{42&hQ9HM`>AYM=hCD{BfCx>(UDtxuomfr9nNp*7AcE~TwH8eidBr4V&r?oOSXdlxM&7Fz0TU$6 z-X)i&CycfH))5sD47j_shU0h1<>?Or4y7v~R?(}o! zG-dX0lY(z!()irIg3z1rwYIK&%dISsw@EiS?6RBz6l{~3 z&e4+~^7VEJyo)|8p}z7B!%2k){w|pVpi5aUUCRe1`m-S@jAA?p>f_JG72vRB)%>Uk zezxy4j~@BHqL5Y1e<|~0GR7ObeWzJcH?fgO) zq?K;?I;VEkWaXNus}iL1$@zutoeIJtzuHrjgP@2>zjV^E%uQO(u>!MJm&{+K#w=TR zZW7#}03XHCqtY(G{y@;JSXlyu6>EgQ*;xZ4u?<9KS9axy;;aYUuYj3RnZeLPe75ZO z^J|X0T4O<2xtuguxVJX+)N!wu>}upy+>SusajGvl4V+&g;5iFsmAWb;3JXe!Gh^=C z`rj`;yw|}AIfKodtvhq?cH>ebO&mS0oFLu*J2Lm0!h$&|2=}7k*xiwK81!2f{|8Q& z0*toO^rxSvYo>_d?`MJAx$Q>#>&yiM7BII$ABU}=4fxKwUnjlRS)-fo`UVUy3R^X{ zu+XzDoVAyCUODo(%l!o1jmE_N%l?D+ea&?*2KZ$5EwA4}n4^`OtQfnlDjx39sf5Zk zX9O@3Wk`AV#?_{HIiCgk?K!Z6q?-@N7Awpy3V5`(HvO{4l7})j$q@vQGXx+Qo^*DK zK;NtFga8$%erS2*cr2tU8r+o`I+W$Uju5b+sH8+J(bEhsOc|uJ+@@Axj5Q2`qGVp! z^E(&$fW;1##l#+JndJyiVrRQ$fk`*61syx!tQEv9@?{{K)i5kl7KgThptIbkSb})s zDxMkUA;7Wo!jkh0Cl*BXt#zn3aws?L3k6Tk>bx>TATrwE;g~^ec7fBeD-U(B>h&qu za4hOmup2)G8;!h9Kd8_EB|z-h=*js51$J^QLIHvcglK|9czNPLjq69xjRa@6Ok)Zm z3(C^BEd`Y35@NIN@fsy}su;@Qa^c-lPuTf#V&hj$;^HOeB}l+2KRiLnf?CnzDGT48 zIQyhE_)D9EFMToYm3wbVzJBY@=j?b7Z4oyj@bN$ZDqM3wGt^_RVE7nPBYv!z7zI3U zcCoN$Qj;7)NtIvh1*QrJJAm#W`u(s^&_VGt649wO6%P6MIBI0eq>w!n5-C^*wqjgk zMwLbKBoA|mSAnDtCHK z3WVnhX|G@{r5q4S3@+;AkHlqs3E*>h)^%{8sh6tyBl-KE3C2xJl+*aQa6!MLj$ZNM zbWIlS5!qqU6$!HfzR$L~NbJpVFj7+LfA~Qe10RbJJmKD8eg7aygoW$}>@1N6hhV$i z!?Gf>$tPz7WAc)2TNVGtTTUz#b0+&X&HF>5C}BxX1HmHa6izYamzYq51?ed)CXF%& zw>A_o(xCNFYQa0cWPK(`Y5pP1No22@(zy*Q#JAr==cLRbv)K~oy=7L`f{Q*C z`rvR2KN~F3q*p66Y2>}|?z<#w1J8kQA>nXdCgu2VaDvimc<8JM2vD?2z5q;IwOK8MCyzP!BEs05$cQx2@P9kM5r?& zB>&VI5$cQxj1%gN2z5pT5>H)cM5r?&)EN;rml1)Z7Iiv=@K2o%Av4ypPKUq-qE3e( za7CRC;d!S+2pnv6G6cz=IvGNp3?Y*Z>SPFYG6V@%)X5MegHk6$kc~>6453bjP$xr3 z{Zl7HC^If~G6eas)X5O)WC*L*P@N2+PKL08P3mL_X_}`_hEOL%i2SLOA-tqy2-<@u zLr9*ID1KN=+d?vg)NjRoD`?Mk z%y*!(w=W_KLX@XgXF*^|b$Pa_lBdNBU2cCVX1BuhNTR7-G^r-<0KFFw%L?S?b~&} z9tl7dohQ2uF0RkT!jUW6|6z}BQe4EWTAkjYPH&Jey@5NyEtxT&8}~Zw#&y`1>h#VM z9YYfI-&Wj2U*b+N*#DA@*YtiW{2;%#{n5i{|D7C=TytGvx8yf-rT2WrU4mb3>^Z&G z$^NgUG4Xft&gk8}PdhkAJ6HS44$f1?g}X&><>FV&>o?G@?%Ti#$AH(GHtytg03ZOU zvoiU@VK?1|1Cfi@vIb%`Ka*02mPIJU3tJanAZPX6KRSDxJcE599~J!OwR>kz@c}_R ze3<=<3SLSdQ7W6doj&)~?tESj=eN{-@|x+nJMIN*E>!3lsL zV{1Rne&#tT=o~3HNkLi)h0T_j&jPPI@c!p??9cx8`dec0BF9GORUaF^ZRy@r4`FLG zK7ih95;HL&w4+~R=juC!&N)qZ7qIDBc0kaN{KLWd>fq8*L!Ses-mQyY>+6<#?Jjfz z3hwNE|EV?mdEJ{eagpbmv(WO+Q(W-rynZN!O!~KG_rpt#@ydghckIm!0)aMKTzLB} zz&6Pp37Lzs*;=#jkHOFF#*-0Xn;d6K0X$i`NRQg%%3U*6VL*<3WvF zrWjE=q05)(9cK=^VQWGH96`o6DrW7WrTYEfz`u=B=hd%o-@iRSJbjS0S58xJZ2c8q z`qf&9WcdD$T46()j|H0uJKlmrlnnxqZv=retCj1j6EBGhjEnP?F7W|U$+FD}EK$53 zi)yiV!T7wLqQ=ie6;dY?+~^bASf$|e3ZI~Pdph?fK+_+t!7d52ElT!V@`hcERvCJU zYsi=Y&NRP2mPB3^xoUjVq%D?H+rI#LYag1Xw}g#9y(Fzd!-opvjXO2w_hH0XRmKm` zzhS&9U|{U#!75Qkmjf)0YB3#>b}|D%klbKaExOKaJa%PUC$kC>CTJ_GN@Q8LN5%}* zLm{HdXed(AEdH@Ipx zAa%JgD?OwnyanR()*!O@UZXITkHDD^WE{^Syb~D1%A*@n*J#NpF3-X1EYlJ*oxesj zCDlWi^`$lrMR2X$7CIrT7+gyF%La!DPJk?#dv+&t3o)BM|Qo zdf^fp2B5^GmKf$Wn7o#(vLUj+!Y&5A!Md>kMjXS=pq8s^2!q?@WZ~uuT$a?X#cE^~-`JSrxiP(6ar(51(r39oHR8xN*@Jy#MG0NQgIj!aT#ParWr}Ba z=l43^7hBaKOb}WQ9DclkErSqmYj9^3S3ET0SobmHST|_Qu@3uPqj22uHe>rR23ZgD zx>j*uF?v-esR;G4VSZlDp1{&dp}D%tixNx&zV$`Hi0{Xw^C|FwNN&YhfFD75Dr+oC zZ^Z|f1_=VO?yRC@R)2pN9vJ{tiwV;U(^=k!gy<~iw>#I+ExYhMt_>;{1;to2oo=vj zI<{hpMh{nmb_ig945A+pvMlKaF1l!}TfO3kOau~job)ZP>-gu_VzUxB@^j%b773t} zunQU-P-!C~h34uS5?c;vFGSkYfnCd-?b#xE^qh}yn19Q{u-t*4$FL6sa}aZ!0smRL ze`9F9{v$~6HHb%@Q!cKi);n}tRb^yYps?ENP$aavIuO+Up46RZ2~Ur&%?{dT-2(dBHiQdF0<%N}Kj=e99< zQUsSekg^e4AK08PdqAb+nUm=3mz#%@0&^YFwWbi+UsI`WLc0}fqR3Im^*j{YOZQc1 z$ANB3p7FQLX~ngW00=rIjx2*F5p_*{;$6FimIh_q+q z=7kcCtuMFBXc@5+x5ihUUQO~e$#-d{j*0zMH*btNgin=l30J8%6MmQRlk5Rg^SUva z-57wo0svbgmBgd=WgQR8hREK6p}B@0t!fCulY`ShURhrZa)a77j%AVfa@~UEX%f9v zGAwRO=bi2hcS4MlxpAxe6R!kNwIyHJ*jRwlxhG*kW{IpcTcZ;Ov*N*B&^$!Hl6wlP z$du!yulqB54cE#;PcbJ@zrFdZszjQGc~cIm+dhT*=W$hugw5M$*maxp`xyyEi)7lV z=mHAh0sj`ssso6$=`;bJ<5o6sX$o-R zddAQL(?_DdKrPNoz^Yr);fzMu)8S>3-n_DedSGK<(10~x=Zx~hPPpgmY*nQf(B2X*zU>&|5Uz|T34GlJ4Fo#}aE1eW zP9}a;cU}t*$U{)Ns**AwutZqdwrKnc;v6;jBdqi%=OuDyH{P^hYS#x%>5bvTg>Qr_ z?Y1H&Jru_x$LF>%jS*e{fGDZeO$0D;9YQ9^cVlW+HbRR+ zAXS%?Kqc%c@D4>7%c?J?nOEg}AB?(cFLF*~b(c3#SnUlOQ;QfBVOEwG1DlW^4X-|- zEMsm(3B9wYR`H|iTOtlT7;|H~xUabUj+0q!QJJ82yE601ZH|50T+R!I%&&O@g63@m z4Eu9c_b7O=8^9_PokYV!z-(nB)g0jQFW{^zo7!SqBN_yr;=6CqS4l zetR$$UW^VBg$u`SSe-QsLl23yNhEFTfY z30V2@)gLbQ(aaBKyv(AbaRH7!{g@p4IYmU-^lonrc(m~JYZttJI?q||>wmwvI5}R$ zWVpHy9Vow=8ymmcQwSymcf6s4tI6_iG1b4`*Dd$jUFdhlWNGKgvD&y;nx<`AD>HUp zWe#BGYy~s*+hQ@x20K9O!hq#ijg1@IuyUpqXdEsVH{RU+iyv2Lys<(1%$3*Q?u@xh z*8lDfIJ<4%zw|!a)1AHVt1%gHBboLLea<2t-1?^vpIE_*E81?{+CVP?wT-h67niF@ zX@Kht%f9|LGv=_bLw?)c!Hb&D=HAEiQ|L_#*zer-J@A;@EzXpTTm2UMM=Rvy7AEpD zJF~IXDhK{<7_J7>lmf*t;T@!`Ghc=Onr(8m}csDl$Oyw>RC zcxUh5KJ8qSFHLr?;NN&J3i*d??Oc6tlwHPYuhQot=VEO9;!dzPL=TW|E^Z)@XSx7) zrvBLlY4DrpFIFwZT+8sPL?`&t`^AIsc5s->3#K&?N|{5lI&`u;^d$+pI6OPik0$Pl zBQH4@f3AfOE;kE(#0`^t7U0iUQl_U=Av1mdpR6c&)8_Ud#AVymYdawlqau5> zkLL%gAK>Ffy#yuP3XQ_2GRuJ3Ik$4o9Q2+wxqn~CLr{vK9NWYkG#A}`=HFR91jDVl zGbnO>2Fi<^i!0}lLP6@9gbmZ*0RxncWX0m;=PpTB?zf-| z;)C72rug&3+E;d3pi%Dt3z_?^=t%GcM5Gmg+ArSxvk#F@_5m+(;7%t%`pzCUN8x7c zaOV20$RzFL9;CC}I=+FR8MdD{S5mNk-%&CzsH69Uppc9E%>&?TF0=Tf%PE_AW94fKQxkD1GujHM-Z^q&{R!3P}}%-HU}?@{Y6rR3wyp)L^L+|Jh1SNunaEP z!Kr}GoqfL0&L+nF*z-Ogz~Yz~{$ke$q`H`bGNbzYf4<{51;bgIF-EG-nq4@ya7vz7V{%5$k|gOhOKO-P!1xgZJV`0s$O zD`zzMT}n~TWU-cCqYtAA{>GH@z|c4%Xr?Y;f0$AV6bBv=Y}|nV%Kx#| z0v}D2H{4=hYRUS%N-~K*qc}$+5G;wY0iqX^1Pdt#%DH_D|5Wf~o5EeJ$`^NWqws?9 z{xvK+P_%6BeT6R}#WbeM*jAR{qg6m-E+P8uUh(FNJ5>zjkX;n%O_lTI#8wub0!q|U zpw67q@$UGY!u-lnDzGde64YXhP^=v|mX*Fj9LoxKMK=@lWA=%Qg*}s+*^PEn`Ndwq zp4}&(LNBaBb*O^&EP2SCEDE^!&<&svpR@wqvhgZT1?Pa4&R(z$t*LN~!N>6-rm;e7 zWf(%R!|~zSi9&$}90S1t3kUT0F0d8j8oC1XAx*(RL3zoSI!%~rFztar+A$JY0%K<> z?*c#i$B*zRLbn2LMTI!vgF%-x-fb!v(}G=K^GK#DF_}izL`mB10nuRvUJ%-vOpwVi zGc7y^*1`@Q!Iv=o60j68wiM4H&s{!Q?!vbxPBXUV;!q)IEt|ll7(tNAB1dH6k@bY> z0YXA{y)oc{udo}lkQk_fnJ9ySgyDjL!3BU%*}(DWil*{u0?{T@<;MGRwabMFc@&Bf zdYq?)zrjH84lK`H;uuil6;wQ`*F8Dkee`WQY?OA!3)H8rSYRChP59ojXA|!pTcrak zEcR6+iRQyca?s)uJh;rD=^Uto15LeD)gQ^<|4gh;X7?q>{o}#~QzVK0CO(|5bi-|K zs=}2k+idd?b0{v3gOQR_|HBW;7#K(NWBbT5+=x|v_(4Jp@S0S>j%`@?M9LaI$PL2q zUv6CBG`tSjU%1!s1(YAtKw7Qjd~j-FLZ;9f$cjLWe*bwhEG6G{59Yf5Hco-P6iO$~2J_3)erI|%%ykLS{ zhC!67TVUJ3YcWpaTo$ahb+($EPRbHOEK+i(34*yR-D!#$n;V~`+sgnki3~&P22dQG zPP5%?M}{tIPgHXt;O870nqYc8e4pr{TBB4e`qQj zq}I8h4w|>tpN*f{6NNnbsb%~eA?*^z&<3Ob9`#d_CgZcwy!BfgHRII#pQqlJsq6bo z+lNn(Ukd$+Ur>;Nz{(|~f&&M-kW;*`%#!1Jn;gz&KqinVp)9&J3x;C>#f$}64@fgu zRA8gomP@1VfL4*E2(7`4pw%3#)=c(EEsKH;f082A@Z^vzQo2+ zo~FF!RFLhaSf&$}`3(aMp(Fpkv|)QB78(ddFu5IRBkWHavqx}Z80=GG(%&L`8e@o% zmW&)3{QsroYcgO~U<+CE!P*WNYnDRJlDO&mloJszm_wcBu1fDxZ2aWjUMv3G6ozGP zd}&f~hv}qQL+O%_3B6PA+VjcE(kJlGrhj++X9G-6YjFc@4|=n&@bkt-%^LjvIj0?z zZe^w6of%c+TbUKOVGg{oI8GR`e&x7eK0Gi#4jB1l3htL1@5_txW#fB=alJ?%U^5Nd zeF)K(VB!t5l?;%B*!to7*Z{_LjpV*3xyj|+f$}vFuaeDWIuBc7&A^~1*YCc64+mY~afFjcU0fotlvvA4t##3~Q7A4(F;sf8cgb+sI;E$E$CG;Q}KD&4(hLFjz&b7Y?f~J~qotl)PQ>>H3ql!A@(b zoz~Xsv?lMgR*6n`QajyQtJ58Mr#t04%`9IueD90&`9`QGaJTrl6nD$p6`!up-J9#P zmfGhc%q?$M(r2v-eeR_8xd?B|+m-aW61?3_?Q?gnK6mAP?pC4Cz0^MU*6MRl-sfHw z`rJ?LbAPQq_vL-=SE0{?)IJZ^>hnO}=fN8GacYcChAAmJ4-O{)Bmy3Wch~AC7>aj| zho=hJmNE2xE!%Rl9m3$Y$(?Pj(;e+myOZkNS*J@KNteW*S1J2+$DR9&GwK+CT_^Wl zYX@x={zd>AbaE$45>HB7i=sc=D-++s6X-%9Q*_KWFwo=Lo67(L2#mn^k0c@h0s1t) z4}7eb1jXhcki_FH78U|@b}v30p6^8lPaG}&&v4i_6^JN?@6CZZ2wbZ*EXa0Rj{N6aWAK2mnS^H(KNswqYW@003Q91^^KN z000000000000000(Fy+U_c}T3bf&kUwC-oK|l`pK|rwoJ2i8)Fmboguo1Vgv~jd?w{dc0 zvUPKEywdY?!skN!`3e3&3ipMU``zZ6SH=U8iPeyAx6U0uqlrggFIMD98~t?cD&|^F z!vp@s@MZlXY6%fGu_ksOlRX=j6(9FW zZac~T-D&${*+3f~mL!vR0r^s{Y+45t5Ce#l;`5uSf|3&GXER(VR+XVHu)s+6j8a)Y zO7I`2mVoAT`A+Sq;0hmP{f_Z?C_vTN)H)iN#bG&;D>$`34!XA%O?xcNJDN{+zgFlf zs3=uug=M!*Lzx(<`}@7c7a~d2+Jrm^M)eVCN~Zq9g%=-5`uVtM@48IpMs!L$8~DiL z1D~iiLamlB6y$|fIJ~jZ2Qx+FMx-U@Uu8g=Qxb9r9$a}`7J@m*TSY}?Q`SUSEjmUwVP=rXn#LAf!qJJijxat7 z6IHc-!Uo*oK}?rTcNx`8U3Kh?NPSSTLyT@}+#5*Zhqq0!BOUy)%$iCVy)gMh<-Y>3 zQ0UGveINOvgDiyOq)K@pu(4+}<}nQ7F+HH<@@I6&f0LM^DNuUpya$L``Y<`&%dHzd z-@$9nZjD5zLBE83s)m!0pw*bd_E6J(S^4KgLnDy$n|i7f2Aw!Guz}D3KqBuLXYW6- zU4&ITZQ&Y%c|6`1Q#>Y)RU9A2!wA``8Gd*h^Z3hHZm5O`^{8t?|yVI9&i#QPy2QFL2==M%A;Ld4LQ7 zYB6>*61$3V#&;=} z%+E~3G)V>@p@csS84>~&+OZJEZk<06ITuuS3RteiX+m6 zDF)6fGhL$HQs0He7Tc-8c#HN?igvziL`b6X`;k!##`biHjS<~dsFgUu8FkLpI!#Ou z;SOyD(T;y}lCdRJ1SqY|$$QfD{A}Kq>CB?bD4`u77v{sByTgji%9J`+l9UDJ zqUvnfMRiLh*)^Jt5QPe+fSeqTPs| zLoPmysm@eJ>5l^)dE`MBLo3;qAjlw55e?TxMU$0-dDUHVw?&AA?3+hXcf`P%D{}x{ z>o}gUgiXTfcA4cr8qKat~>uy-2|{gX%|SLZBqB!W9T zo&OTd!PGtHQ>69u(7zQ|QGRNO%K>N852cUq*gyzdGuovQ>pqDD%x?7)nA$$q?dhHu zgkpJzhJnOx*Ah1^wPZ{q;mI2U-R_pn)T9fuHjh2@&lYdW+x9sWO8R)?_*Gn)^7>Xi zkMf%Z0+-B~EQ$KpadNkUkGT^93$O;^6itt`JgeicNJh|lnoqQf^R|QwtBjAZ88N%1 zsagzK`>^YvorZ*)PGH^0=tgy;)urV3xU4xMZ`pEq`IF|ZmnkG~T%D`KAkv#lMbR+@ z&+j{q!y99QURjYdZmoJAW@t(IQnUb4N_YisQd4;_!QXgLQD_*!Yzo}wc+681NrfKTWMkGKMuCBR@Gx z=ODGBF3})9v58wd(=s)0%mC4JmoSe+=}~31cKA?Sc(5BGfVO2e$IeSQscz5Id{oXe zHOJWm><&vJe1$D6toX3#V|vbMRIN-vjVP5i+0 z;k`mCpA~M$Hhy+@50tEx2GCGSy^g^ViG~iqN>jJjgJiB37CPW1Op;oMtgO|6Ma8tk zOg$6AeuPx+!6CUp-a8Po0TYHeCR+EG_@`UKnP10J{Qv|vQPiU7BB9cs2IZ9f^!hfD2u1{OF~j%QfFj>so|ERjHq6~X#?iPZF+R4kDu z`Dt>js;xLCwV)2%i(Oi-elxaDi5EF@`O$WV1v2&1AKqg6{=ReKLIR4=xlkLUH+?+2h2*CXXpP~H5IYdK`ss>q z3e6!byu_2-%$>6$=@q50YZ%{M8B=CtJ8jWst zvDfHa<;4TpPa3!`zO#w zFBa3N=qx{Ee@%`@uJ#K5{UN0M|HN&N|Khfj+LIJ&HVDYCYX}h3|KhfTiH)PWg@d#G zf1&$-2JK6MFSm`3l)jyRAH>|(Q>)im9Tc(|>43-S=7&8k>buyyXG?-axa6e2Ib<4v zt9KViL4A7q+v-^v+GC0W6SOrJ*R7eQFoSR_It z84l&<=0EJjZ#PDBu9Dnli>JPFgL0y?qbf<|O*QGqc{;5$9p6Ya%Mt|Ts|uYk%h)61 zaKkWNppuY=p<@!XX8gpV1CN0buwNAMU(VB+RD-X3JV+;JV3vTRrbsIq`1wNRB$b|8 z9BLITz^ey=MQ#38K<`AmbZtdep633@H{FTNg+ZFGPAE{oE~i{GsyR}CKE4i977cz_ zj!(f!_>-bNkY@(Fc{G*=o*!TN3VSs$%ycFmQ=d814tbNG?@)!pG z+CHe?%@!wl_;N+ItNs=!!?4kTCSMndgOr@e4nG8ngY3V)Oc>iYvTq57tD7lGwCmV<|eUtn#! z^)I)Iyl~NKD+Ha{rDb#BHZ}!C0}QSRP5v#%dllzmMGjT|?Lt7$AQS6m1CA2s{FMVS z2TUh$<+p=h0}z-Q@$H0bnQT5P4+`L=b+tNobvn1^NUvlxb~Zf5qDp_rEx~7CCHphB zT_nc6v%T@W>F_>a3Ko|Q!h^`jDI?kaQAW62(p-7@*1vC z-@MgdyIU2?n!eb@#^q8L1|ibHIzsbXyltSqzqZYug{k0go|el}p2V*!_=&ZSE*{7} z-62Mjwmr5=KsgUkVgksdrvR9T=D7&9%i%;i^|FC6+#D8`5NZl^!7C!~01J z-$aKN^H4IBGT17 z9RG|t`!~u`{C%?}BRzgZM^#p&uq0f}C-bsBI3sQOz+oCMMa2W{BrnSI#!RKn1~=fMS4~lG1Nu7J_(7wg0XaNdM3BFHH)- z$m8?!qI{K?rVB;C=Q=NllTdc|J?Z`gL?SPaQ)K=Z>t%NJo4xCC7$N#9Wz_)tE z7x}CbY0s_CbX9#oiq99O_+!0#F_TwZ>>H_6W{8fOc8)obfu572G(s!eYVL|PcuSDt zyUuP5HX@@aA6z)TBmj=lya~LO$U9euB6JvSNtv)kW-a8R*p^$l= z{b!NNqp9&g73i5+BTJjJ;d2O9e?$lFpm_c1K0sJzo9QcDZpS&l)SZb{JusZ7iS70a zMM9x$Zi=8imlN}O*^Pa4Y^rx+%0q$6O@7NhRd;K}g}riX%2xFrvR2iR#Jr_DsYj!o z$sBQ6b?SKjXb^SnKB1!|AN8=?lx+p@7`MT!>EeFj*R(9s&`{FBsE;i9ef-R_MT9tJ3+lN67f7&PhU>GYN1vUb-IU%1UwATu8Bwx3Yf(16g%85 z;%RvHk6u>ZbYZyolZMa%gCiHv9Lb8Ua~_|D#~eM)m`T4yw%1{w(`%7yBeNBmc8K;y zxdkWHnp<{JJ52#+1KUtCLH3NGNxCr;1ymZeiK+>K@KGo{u={U{ zsSG1yIvjoAxg4|VGD=sEYjvajs5rvEkrM71gY=ZYv&pI$69TG(E>iQY7)Dlyd!5zP zl3;HMA|=E;8ZySmeZVI$D6^KwFtlyUm}~az+6~blijjqcSruG%IugQy9ZXBsaAXg- z+Pw=!FM{eRV$|$>oebXPXKulIAQB1^<`W^#E zk@vn?b;Mymh+%h9%`;*088cBJzN70i7r_g{cFaxww90W5|1CK*;Z$91H;44?u(G`{>j?p$manN$YtM`9FOGuY76$o;4AQyGr5G~eP z;%}FS>aNXcyhc!4UD?P@tB$&vChy{lRukWi*UzuS9x0|5mXY=^l zaq*pK8VKpED-yI)1 zvpDQjaMTnEhBWh}+$4rBncXx=E!pk~y^b#%fC4PJI0q`9-D+ zMR6WiyByAEO%9!fo z=mPq%K*Z_w^5>ZiE}%Jvnt-%mM%1>(ES&f#k=Ux7UaV1NSevsc3V|l zO*-_0DJn6{<(F#7(3oP6HpYiXE_J@+=7FY@;&+5G0z!FOb&XxSvM;*hWysPK>^>UG zS!Ht&3c_Wpx%x%iz`{5Ynx-jO=E-a3d5c@4*j=BL9n(HJ6<4ztKj2;irb>O%N;#<; z1gQX7JOyDBp=RUc9U*UnH9 z=9FLNj{IsF9nlbD?}Bwc8+3iWB?3x~{(ZxL=qcB1Av1?Y%2f*q#fY*Dh0l#EWO1b~ z4ekXlK0nJqtG!PIPAZ;td%&n~hwwuO2|I7s@4_p8N?C!W)?;e!=46ytQz(5$NifN2 z6*SdpD0RkEB0t?I%&MuP@6TPdF%ra}dVWz8^28rI>$0#rB9u?C)PSaMYc2`Q|Iy^` zrTc7$&~XUXXs!5MPms9-68>gr7e8n(z4(*d4)a720qYUci{)1y35Iyr$ypK82e(#T zMIQzJSbdy`xIApak@#?~)YGW3`UzDePMM0=qxpg1;<`e-K%EKJm#~@q0V5KM{@Tna zY43B7D1DNZw;Qo|U1U)QXKY8J(b|`aGgJD6yiqag z@xTgvzSAcFtP8(N-;IsAQ*v?LaQa9$WdPNSx?Q|&Pif~OnL6tu|CT|Q)xR7t&p*t~ zU#RrO3)OX+#TO)S`tlt5ceW@_hTS3)c1B+P0cBM+6vfAK< z`!CM;z@?>D0O4#7n7e~gX0MB$M*8aP5gZsVI3vg{CD~G2{Z0Bw{eH+w#J9*JmUHL{ zD&T`=pOxL0@|Xes%*B_WNmuehb(j!-UQ7X)%CUIcT4@xRxy*oEU54VS^A7Kl~(4vr4G2+#-uKp{?m@;RgL()Do*HG^m-xlA zs(3s165|SfATa6Q6z|IUTYOW}uzb)@B-@*wHn<4lW^8HXkDS^{P=E{C>$Sr5lpou4 zB_pp6{>nUW{PiG-Xh8x&Ay?(AZC&XT9D$dAq3{@MrRPALs1#e_uS#gHo?vy`6Tw^5 zi!nADx0=R*aVM6tWZf9baGs@3VkVD6ZTB!k&XT!kX5UJe0vAjwyFjBwYz%t=o zFG?GfGOUXYo6LHJuTW~|m`In4cmsHgrU^EqzCU5V5WzW z&F_c8XpYX?jm(q8Z=xf|HK>WxtALQhLpEE&(c(RLq-->E zxRuU9(}k24#Xmd|iK*qp5P_n-D{FGQ4Tvj7@*`gJG*N?ZNN)(;gRYRc5#k698ahe$ zr_{t6@M+4av<~Ip7cMB`UWeGxwnS$SWm&QW=9A9*Gq+Z^@8%~98OqGl3-tuPDJ&C| z<6+?6PMjqRZbSFZF`p#KA=x!7lcin$=LE4hDv=B_(*W;m>Vt520sqYYLMg8)WdX1! zEWf}Gdnk99U3}^9>`P2Zb9S;*L^{kFxA*Mt`p!R^a;Bf3?382rN-{U#RETKA2Oy`E zHuCR;f|y#0p#!a$JK)x2z4#OW}2r!_|lusf4)W$+pXpVwJzj$&SUtiKP=*3QfuNFD@zzHRKHH(w6OY=^d4 zCD1OybiTLDA%h)>vtS22Z^b1-u~P9_k?V2=ySw3=_YE-iYm~G=ZIZZ)k5+#v~{#sKmuWEkrvm5(b%+1gqfm!@9Y?{@ue#`@NNNRu( z;_dL-S%WKZ1s7;6p#F8Js=3N?MW5ceQaI(g4)Y~^*%Fd$nrV@Us#R;>aaWUQg<0>{ zU{&A| zkM6zX>Gs7Vh9j^?OFU;I->;{9SsHu&tb6IzB zMf0KiPS-+<)|;S&bigZOsu8l>JSg;-F9`ts;}XloAa;TbqJ8 ztU1d_(_O4#dG0|mHmN!b+(pju6qROfXMYJ{ar*>8$dLk@*8|5zMx* zo#m)s)|VSgt=G~N%)6lczgHY+al7I)=?joIR&L0n~z8#;&GuOei#U#7b1-_P0V~Q z8+r9#%T#UGC-{sOtiq6D(jL|&AX`TZ!Y+V{8fppX#h9E%!;x{f1z+OS<}n=5HYCV2 zdC;vbvoM7C2OZI3%;S2TUbsU&$X)++)F%ho=^9s=`6gX}qlHO@bfQt~U!i%f5+D15 zzT{6TT<SzqDROFG&p~sn4#Q0&UdGLbsWOXh0mVjD za2r#NQz6=_)wV>3bqQTvNu)T>mtv-}+|S%1j!HhAmFSXwsBWf`Ou^eQ*@r_3N4|Wr`*MWs%ALw=7;rM;V2qIXnf1($t{qljIg+rr z!f^fX4{(Z%sXc~DAFgQRXn7%g+GG)9`Nj>a89vsYOc`XH17btngn7~ibDLLShI08m zV21Mg9XLbTFfa9#mbNSL!%kXz6+)HD7%=OR1nJ!U7jV!*PDX01TK=^fxOf*-mz(kTC7Xk+OM4RcR{f#a4PYDKj= z8|QrYQ=)Kg|ddEwnZ{QOjtxn8_dQl(2unBZaJ1U<%4}WcQ;5! zwg#OMx?ZBIx&o{Nr>_NhAS$O5q@>RF#I#M3^ZYgncZ0r?;X}4)?)hUznMdM&X_8iH zz}R9glh|0j^y3J(WMs|JbTnUv0W^r~%G@chbT{1URd4 z7Eb5>+Iq|puw6j3AFTc5Xd#2GU0zs&@MQCp5zYW1CsHv%_UeME`x(J+W^p^*W2WW- z=Q~Dqe&jb!MQ{EZ2D{XnKQPbIx!odRYxy2TOKl6AsDnHGaGRsB|0vII^&d&{_gJM` z3xFf*#$=5^C+*fcj|W%M zCGoR{ceZdr@!uC{za~9T7(4kjeDd8-@9sz-BYLYF;#~&pI};TgDoQ=bJg<@%S(NL) zNZi^6QX&HAcB-r&)>riCX6)W2(e4SIJjpGTI9_`YyUuu0yC2 z!pyu_H%);LMvFOwAjy>WlcDIlkW#{u%9)`}g!QH%RJki~<{1769}Rhxx#vX@6355h z+vv7!B=I5sTP}_q{#t(-fzlVbp!cqLbOJS#(d>wOk^<*j zm~Ci?ZH;8ZAD^3j<|f%3kUpt ze_@7zMOss^1V`B6U&j&HQu)X_OO*K`XIayeQEG5k2%Eo^$&!+9M9h~bSOUG=z~0Mz zHr2we)_yC?`pGwe)g`n;%nNPGJFIDG_~Jk!gyut2bFB*W>X?a!va`>}5+`9x&qC=~ z>liB1?qM0$HG57_RKqH4^nx9;NWaax%$1&E;`zMa~S!sVMJri#aY@{1x`#(<{yqp2#;Rwd%Y8ufjrM0aG+rtVkFS!G2M>AomldY}S;|e$T zrn3Pnz%EomwAP}>pY6W00_282D?$c_g~UdA?$9S&xfk0qKh;l%*4AF7p5qQ^WjqI9 z1gDbUh2b}MVAXoSlAPalRul%ANGXujzlxuY+$05iX!a6`%7=`xL-0buja|#h*UDMH z83cWm#2$nV$gjS%v0BO_2M3&n~vTrN~nq{!%9CS0*5HTM+jv`Ok zIgI{MwJ->>1XG}sQpvc+Y9@@0rcp>u;hu!lVx)9l{#kT({;^^CEvozU!S-(=iNFap z^j0JjpJ(Kx+`-5YuNVK}jG>DccB%ZpR zC3&HG)zM>UO+M(X1m>pZvMYd(!mkvjCNRL_#Xfv59qHU0-r!qs)yvwnIQmK1$A4kLD1XKB*R297m^Ly%u)CAmi=HEONH^nV zh45`8z?f1C?UdHNPfYbiW*Ado&#tjC0M()9Ph4xNQm7SkNkok)6&{u!YCs)w2uZ0rX!mcBJ6wo8A$CmBNdCExo?)&J}Y4U%6nApySu zh9~PSsD{1~1h0$UvPH{ou?ggG_|C^`%6P}{5Wcw+Jpd_Kez%YC#qk_(mcAy!2P%-T z58SCd)tEz6@ry<1Y7DAJA?6WkA0t@2JgQi zSh}n!W~>9!iAX4<<8zN`Wr#~~1Tk)MF!0{+N&YV z8d)Z7PV&7aD7ERb)HTzPWl<(nJZ)ehv6eK0c`m%$+;B@7fBIpoVe%UWvS_lJ_=Bm8 z5ZPXu9{FPXyv}RUWOUy9bKIb^`T(vCr3ej~jNg(UBpn(3#1XVahF!=L4Mwzi!!1(^ zD49hS|37ga>K?7hdJIEC=>j2jy2-S)kBlFlmb@H?r0@%$UajF!?y zB>LRqS{|+XD^;EN1|H{ef7&1zo8k`ewrI`=8OomfRFfj$BIAE+M|}&!#pfbuU;eOb zMKgye^kQwM+VCS0>krInzZcW_#T@(36uwddrdoaW5QcI`sA<^y?TzaAMPh@|pjzIyYo}8*-Hpw@OTVnN9CNhuLDRJT8 z!!XUwMvoxMbT4=t&Jphq#+u?o@$Xn9_a|04D=tc@JH90)?vGiD`<2~I!9OXR^=5M; z6Y5|`-=jpHjGOYi!^EoK41*uy$tncY z>Dt6+w2AoTu;tTma%2e7!6TTb(1HBEZg&IO69ua(n{KW)PT5B#yL8~C2Z;z%-RL|L zlkE+JiS8j&*C#97OozGcu@D7yqN6QdfdhVz%{`%Lmrr+J{9Q-vERY*G=4J?UkKAMDT7 zVybMai*{WNgRppcxP_^p$y@hE_Tq>r>trITB=1d>^|Bf*c)uwr-mK19Ixn^v2wK1m z%~n<4J9ylNrAkWm!JAs%c3kAQ{0ER?tqC|}FrJh0z9wo~2WT0a49Erg98_2E040Evaja1;g{!~Yn2@~WzhPXdau1j{O3 z#QxCoPkWOc3xdU{p{yVYNMCfD&o(`hO<2xsZ7}ku7k>qB3bt5H3xIW3;=BHlv#52{ z;$*=g+!rI>OJzlRe1Tq=rDtAI%%qEfSDS$XPz!t%lYuQcyuwX5NRn5ya|v zZ|@zlqL1d^W}o#Hz=q;A;OZ`cJvW%eB6l^aSop!1!w)9m^BSGcMKBu z`vb~touy4;LfXogf0ZIcQgKZTzjz`w1@XIsw_5hDVo5Fz(!sG)vzhMLQC0uybw`vs z!~B*2OfSrTT*AMqXPO*#0!Jb}$1GcW3N=O^Lr$p_7bH7|qBrd23W8SEh&B(|2i1nv z)+3V8-E0T6jW|P>%ASi1F@J89{Y+_gOu0^|!G}1}pYI=-!u^MENce!!stN|nlNVEFXtM|@$M-uI`GG621p9*U$mqWYR#ut-SYY(YD@{zMYb0Vw zuN+h!>S*|6yInSvGbe{;(vM>?=I=T5W5EitKf2dkLyCF%>{h%TIkU&FuH9l^B|wqdRw} zQt0NOyTe?|1vYTska@xeI{7aHooc4ITrY$@F_LKD+tHHuCmn)U`f0<%Ixi{4MUB^= zMtkO;iFVO13}y>}s(8s;L1!lPsgrOfZj^W{LnBUe`(JZxM~?vYWWE#M!|_FINgcjB zETH*KzjGL5!5eVglw)1%*Vu8dc&d(@n2hkb;lv~W$3e|TV|Q>cys`@>;3^Zd!hfb! zE1tG7y3EVBSq=_U@ao-ne#)_>570vwgVq^%*`|emzIh3Mo=ebM-?OX?)f-KZn3!;g zO1&pY9a1}J#B=nzK`>E^l4$xhv6VuTsvbkKQnD9g?1o9tLPy)KtC2Q6u|itmzot5@ zAt&jotG1-ffEDN#*&^v*8ma9~xI#Q}+o45_Rh{kgWMUhd(e=#o`;NbXALGu4YK2f% zjKX!V(QBzVYM#C8xQRwAfP8p*Ua?08YN96mo1?c)x^5W9LY7D66!+u&Ji32fK0*xE z)L@_;<5U@4I~TqgB$7c>Ylb3rY2{(u^og^sMf(VBQ#Gf{KO7K`rw&11gDVmRHLl@fFfX3&#f1V4C-6cEEnS`#5nBu7ls&hg&*sXbD9+3iC4`_6%3K z*I-28+2kjbP?Rfmg08Qos1!5JGHpVKs1?2Y|FxXZh9?L%!n$>Y_Q;&KQANLwffY>O zCiwATdx4ie?b4plAXvb^a;Uje^jW%CPQ3q$^?=ndU!sIu^x%0i*Eq3QM49;DiESs3 z`3HuAnPLLdR$U{IAXIyve&>^5m;U0HaFOv6kZ?h_Qbm-~;(hpoU|dM2m)O+8p8D7? zCVa#v89Oza4$mVkRUc*9@roYQ_DMFRf=86!>Q42~KGFtG^MWHER_BCU!31ru-m_pj zobJ3FZ?;aFr%QsMn$|m>-Gl0pKhhSCXQ-MN{m*i9PN)WtmenBrxv|1P>)tZAj@2*q zu{m8^i5vU;HRXaKP6zU#GhX~Z(|0)`8r()!{d~)O#_Zm_)b`IjLQk9no(@QBsDC|p z)TBUGu9Xp$G_e$Pu+#F3Q$1`l=eUkA2%lo(+ExBtgnib##ASfGc57kK7+~pU84ZZ= z%0NI8l<%!YwYr<=KkBT^j~i>f`2DtGL|R0cg;QK482oQ|4VNZ@os+-&KY}!$O8@JL z@q#?&p&?iV$^X-(Ra?|?WBbAj_&7w#&YBycgJ_2nsUO6nxVj|5 zIe-q@FA?&V`K?JQdhvj5IDZHm{okiLQI$?b+ayWw>9y4I`fd4XO(nf0lGj+QuqPYr0N!!K>Y};AkrCaTz}S^RrUN(qLygiH^Y{3 zINWbz(I|10DaQU>|GKQZnTb4k5dX_E=U0HZOEE^thG zfPYUzg^f_MlYH)ffSkm2EZXFWJ}xDe!S`}iinoJxB1_MO;$cA)dVBEO6>0gV5*K$cEz@8 zJ1+sh&+gwpU-!%SxNo-gUliY!>Zzr~0Ql{GG3mbRc`l$x?&Lp8gD>78WzY8FoQOIz z(tnr;Dd1HdM6ddel}|aO z+Lk1~W2GEdaf9j>HK-N@$Jl{|ekp`9qbbwqE9KirH{NFyMG-u8B_Dn5X}g+~8}c#} z%!lNz04orE6}3V@`8YE5YEwmosJ{B+t)Oa`lY$xSB$TsPEOM=I+uEURNj~bNfeU6E^;e-Wv0y z0<&q7O~v#PR_MEO(no0I1%2~pC7|y8ku!dNmO7a{!|~=Yb78w3>QiX|MvEVrh$DoJ zC%BQBd5Khv)jadnni2H#ejm&(0>1!0vg^XKfup6TO78}3%NWr-iLUOje85a3GG;eO zc7kz780lLs?B;u0z-MJi7;C0D1AKd74jDWkj4RSONgIlH+x_zo>EEF1ZGyh5vsYyw z@4n}0cl$s@aF^wwkEU2e=0z1}YzFrbN2}M;6GqTS^!}%%Q{^VPBDjvpz!ytrj{u*N zke--Rd~msde@6F{t%l2ki%4SpR<G;`8 z*ZVuk&DQ%Q2YxmJF4H_5tK9UZ!+ElKCzX`BUln8a@n#vjhAWMX>WV zUn>bhkI#`S+++fclYlgdrx0?YG0aeP{EN1fnzZc2ejwppfMVQog22;`gu(XzOUY0% zVoZxgbVEXKD(6tHuOuA^@5ulk#Njdi#@l=Y5GnNZ7p6!6Ka7{^#5~Bl?J6+$=4WENxMrE@Q~qSUwl%|OB1vvW9$w5e>40op}XJHQBc7F%Ftkn!^RKuUaCLhWDv z;AAvEknaXw5 z+qP}n*3I{i`*g>+@B3-h+*PaAM2$cz)e6bBdi=(MqtyvzU3PqO`8j25#z)u`bDriH z!%u$_9B)IiQX6XmRv?hMM#9bbD&d=Ry_*boSind0>)6XoMIQ7y@)LRbWP2Ell6iF~ zpQfXiSOMk0F&~=Xfz&~bqlD1&H=LT*QA8;E1E+Z2z*3^!iA`_6iqSy{*F#<4!&5zt1|vWb1DT!tu|Im1k_V_P|1 zfmPfLuO+fM)VR|~0bZn!`U#nlao6zJvOR+YCieBKdFrZ;^`Q(fbD$IO0ox={@D_NX z;(rg#|1t^DbrGrH@V{}Iz>Qr)^QeL}#`fs1r0T3pioHd5&s0QzI9SP|hDPeF%yKvM zz3J;sY3;GGotL%0^IQ89(a!D?rd&PYwkV<~$3cAa?!k(FM7P ztMZ(*?S+hoy7d7Y&CVOBxnks)pDBuoeD9>E{)_9L$cd<^i~0bdscn-|W$E@Tj&k0Hw0L(gU#a7xi+0WeL} zN_wkw>-pN#kUne>LZ5cXlh*jF4pOrd5@`@)e=o2NfWiflCPT#{fMs@of;%Rv>TC z(lNnLAOZ+vwMg&Ppc~EE6H;dK;GeG==tI=?-+nv!aeR+q4QFWXJ=>2nxHeqyCw9*$ zruB9+H)espD4x?8S~fEv;cqKi78f28M{3cCYIRpBi4sCaSPZznUGi(LHS_Km6NP1~6rxMf3E7|Jazh)p$ECvC_na)J`8L~CS(g? z-><{DD{Q##`nVblyN`=YH%2dMc-x+%y0sclw1vQj#U_CMJv;rjwzfi-JedPSkZkk7C#MiQTUB(Nr4n{~-ZiW=%OwFyh;%tGY`i5_ru#J?KV{b;@A2Rq`t6iXT5HV6J^3#HGBJKknH@J6ne!0mb1tdC;1 zK|m}9+ll7s?#3+Vey_uB46?onTnbXZn~;86O5f%D1lM*>>o`f6dHNaGEMRibZYSn2 z#4S;X7Y>y_5|K$>sXH#&=52ca+Q!YPsoT)IAJ9YaU@}zE6m0W$jDmf+r*htc#Ew8( z?hKz1>O0GPhTwxWet8~7P+NqO07<6*zNLFjVn=m*8A5*fhjT3jVlQ5Pw#Ksgr()r z&`6Qc$ZnF3tX$awu|D$Z(jA#Vnc_W^Z-Gt#J#H%nkp~{FrJwCY5vw~N349o5#sh@gM_z-# z_ZNl2b;$`7JgnJoxMQU5DBR`+u%wtM#XXa&hgQLZC8%=ql(nSbmeb2H#?of8Q*!f1 zZVdH{$z%%^OZJU7cODT{JEJU3o6VDWvs8}u281<=CyH=iDW&#H7cWXXB%gTdXnl@~ zNghlWyiscJSN_h&nF&QDcphbiwqV}24RpOH8Gj{lhzODy&$Ko)3$d#I*9<}$*B%=+ zQbK#EP5QIcD$1n|!@?VenB+WdimaNz<;$<+iCo+Y_cI&$md$SIDX&ydg0V9l^|pM1 zXN6M)8*fELq!lW8On9gyJcG}4^(W4vE;@>!Y|h@qAdUY8h64Tv!$7?x!0{lu6J>!X zNJ5}0L$Bl49N&gRFQ;DZGGPUBG*bK=MnLnF{>#tG6R5$Fwn_oE7$VZ50v8<0KICH1 zuU_yVKp!yY$)>VREu}j^DinH2uMs^!t?p=iQfQg56h47#9XW*>ZT3lRE&x^XR6RkA zp)y&;XG?C$qWCUCv0dlvZ=YrTn)DL4@C7y}&@BuU&0{H=@`kU z5MOA&k6u{JYQJfJe`YFd%5z1RkD8bTP&)if1zq{s38*3S1rsY3_$S(&Wpl-*a=giT zf~a2Ub35Ex(9a3iqo=~gh1jyF@UHn+Ml(mipKL2IMN;83XNjiy(=3aEodwMh>ncSq zVAJVDpG$)|{%WITWALzJ$f3gDC{uTmx@0xS^)~XBOM|oQ+_N2t19V;@&CKnBI$0Pg z7Y^hsH|W5!OiD$&Q>kP)jJ+Coq`m62SUEbj-5@Mb=n9l{iAz>%UIr8q!Z8u%XD6UB z${Od$I}KeCWPx1}`JNbgXFVgz-BTiQKoVTTZzlDB0-3-;1(1blWVk2F3-R`C}XXVFd5i ziJhdKDiB=((y5h%Q_ewK(0U0(;pp(>-9fx!;|W(P>R{oaN8_CF{zABwWusZwjm3Ww zHs^XZT|Uy)e&0sRpa*>3HNCR`ebsg-MF$a)S%HC%x@6QfAP`)hGHj6VO_$RZSNIhd zFtO|-P|Z)&ge-jPfZRP88C z77BhhX*X~5F@L1R^=?|G8iIGOYxX{0sBznDymvigVdhVL(T9URj4YntiV;al$9`=e=94Kj1w7J zNYU!)rq*$%+V2QhCz!IJ;9Wh5T_lv}h%+7PB!SWL$N{w3Dr+y8HxkJp|EkPPFS&?f zWH7ev7V6%h9MJETZjx8bQL0dr0zU+mXkKLGFJOZS`;R&N8#o>m&sO``Mua{km}PRG-Bl4&mI)F!E152t}ZVSMVnR-|2l{pg*^{ z=Hc-?jm8S_y_w^6(PE!r_^N0>RUWc$Z}-AH1+#*KF6U(T+yB0no^}y%y5*Yo0x5LL z1+QWdzxsIJ@4!Ca7C*GU z1O-x|>^1T*(>^|&%YNlI7YZht#v*S@xPA{X8D6oRBf6+4n)n6Y*^rDEO1L+Eb4hNaN6Qyjcy}d)8x;p2rxAtlW`$5 zRj<}MT+DJ#sq$Uqmh=qF<2Smo7C(oEX&`F~pHMQksH0l>s&cm>H=LSl`PsOJf}>6n zlb}B@7!PTz94w*1TV8~x-}PZ2a~P@>>%eJ|Kw$>F2{9^3wo7A#AmXn71u)k={X$5 zfb@#`Qa%#Hpq(=RYtxu(wnCXQ8QD^hr^60qTNLKv^MGZoB|_P-`{w7ZE0Vh)+cbo0wHSR11SL9cjP@PvOBDq zGZ9V(n?Ej2&6P>9AjL06`JlK^+W-5SO&uf|ULOSx(~7lxMdATjV6HUJyamU5*9S?WOCI-tI{ z>W^vzgV1FL*0j!y331BWtsx>atcUq8gTb%C?2&u%%mEuWvRK~k8?oUGQ{)qvE^`U; zNieyA9qwC-+vLT8ca%?mXRJ_C9M7PZ;hUkzT67|5etzZe9;G+ud2b-q2<6FZXmHKC z{Q|T{Xcc$O_n3Dnmn$%7CoS)0Q{GmZco1#%926~pf@xTMXN}a|DSs_4b)NvBODgY< zEx|N-1<#!$+FrRt$gosEe>9RU6{H@^m9IBFk`88gEc*ZCB6;*A_vc&6YFG4^Ju;WN#?fW08-&(^Ov3$frF>e}~q-7)zTKTX}Eu`V5JY zZJgG-e4&nT^fvhuc0690L63WBYvxT#y!7JMu}>x+%w0&R$|z3VH$=dgYick<4{K*O z@FZ*%Cmvc@-cBGMgct^i2<9~)vKo)};;4mGiG4$`3kRQ9ks@RU zB?+$!y*~lR_&~@X9-~?;`tWlsI$Nb2mdePeeAXENHM-F|kFTG3(!CPFfmps!W`myk zhjfGP?;d9;?-z4Hil*>Zb-XYp7fhF|Rpf3<7StSCFzh+9JoS=7z=M;J+_1yg3WmBq ztG2#9HF`W?pH2Q`g+;jsqfTd zfYL=O=*mPyGZTrEm)rZac|&BtqJw)5&S7!GY`+xtToF^TP#PfTv4C zK7e#21A1qAV+x+{hPFe8HTfv;G+r*;MJo=lzorJ*#m;=CET$3ghQy1bxbhR&c4t#6 zc$l!BvuKd=_$|~an>QcI<>f#DEg`RB5;BG0@T8ompZINXOrE?g^o}u#KlOc1WX+~= z@%~sX)=lmYqWrgWtv%V9ev|UocaT)gARO;4i3)d*5T3R)*jg_oivxK(~@<$H3>xelRCCHp)!a@L?*mHTyHYm z93o@&da)K)4M$b}cHdTyCovCH`m4pzeAMqAhT|x>(OQG|FD!u(!&X_Q$A$2H8TNX( zDfvAL2b14YT);81$EGwrgld~@ka|jub*Od;{DCz@PWNqzoD|gnTOp>lmEYD>YHRT)v9@zSUP~V;Djuzppg;1ef9dwX` zbtcU3S=coFNtH+@-K)d*33=<9o!FM6K{y*`&3Bx5x=yyRgu^Xx(6N8bP6|5{zbh7; zj61QrrR>S;EtI}f<)RA!7} znYu%G76XM`w(p&jaC%h9sFca)2E6FW8G^v)1e!5}`w>{7IhZLh>nsU;Oz8_E2a^CZ zyOTM%x(~?z3Y?jPj9$TpPuf##B3omLQ|OWenss509=(td2CWXTd_Qn{c0NK%LDRGQ zVt*oBziOyv7|?{8-eO+w*U>a2LQ<6ZuQP;$za)3p>?Dzr$m~@$IubIarj{^olmCencU-f-qxn6Ve#f;gYLqJ zd>|ZHD;2Y|E@xTF=3`EuZMc6Xm{!1sLM|A!1gbauL;xaS>J9dQIR(1hQDeSL8paci zfNUcNAZ34n?xAuH%Kt=^G3M+d0iVT9GDw4Wm=4c*S3n8(SbAAlKq zg}gi40iqM+16`pjRRKe`+Y3@&!Z3p#bbdDq4?k8>qxTerNgJ>}aln3i={XJPi_|Uy`eg0KjT9psJmnK2_Xn;tYLj zc+14SmyC?=$<}u!U!{RQ9ReK^ML0+W@@`C?fVA{}YBq(%T8buZ&it65BsdE|(Noa3B?Y^nuR~-vQ78Ji$ug~l>)^ha=DJfn!WzDG?R)+JIbcv{ zBBjWyf{3`9|27rD-*>$1yo?o^F+WFOrT;NW@Ut^TRO#YapHHjNsTDyP|2CrYKGYVz zqtujOi?&h-0-3PPy}Ouu6TOW;@Ty(v1E$-saod>KW zcU+uBdA<+fmQ=)>-~9{4WY5K<4GP4@@Y9g{vkG2RBC00`S!&DXB5#D!SxvXR&)BM1 zcHzm76&g*kN;Jq()F38q-q(pflGMTXQ>yC+={fZJKZ5V2Z>}iF_AnAgWdMCeM-)Xv z2M5+P2>EuYH71o^qZ;6knV|?Waqac!4}!8ZII}d$4?9Oe1YrW~26*gGjeJ<$e*Z2I z(4Wt?Wpt*1)p9@n9MyavS)!VCmIT=AsVzMED7*$4D4Q!%C1=-4po~(xLC));(Z|R+ z#+G?C;^oDeQN2q1yS_VFT17(hC_iGUe~fdyidirHOFEjR!Zs{d*>n4dizQx`Bqscb}6pEWR64)*??1FfH zpl1_8AY?O~Tn}PyUAqfaYeT4P05g*GAl`G+M})_6Ligmg3*EH+}hcIHs&Nrg7^xIW}{$$Lz- zsLLrm&lun)q5ZGI=U=qVU<}|mrV|Eg8VG6ZT(w-#94==?ScCtGw}_*2X17c~ z(HE>)k^T^E$#y|*UinKVArlFm5mGWTC>kubh!qY|Jip{H2T77ZUNroN>hRScwcwzc?}THX2}LAZVH!!&bbisH!eYV&5TXKD z;RPCEbKx#pUi699=_8(9q#G`tjmhB@Gmh#y?Yq3|y^+K(qp8qJeQ-ioQL5WBqE^8g zu<(|sN-kE^s_P@SUP)afbRA0_zH>E1cZK){{=HHOdeV=&b^-0RK~Al|Mh@sP^@9Id zzF@&3ed{%l1aU@sYsKwRZ7P-;98K7x3h`zCH$i-;*WolKb!!mYUXDumq5ro1HY-Mr zA0IZ-&Tz4;L_Pj*{P~!cf|H(N_p@G+`xOl;=Od~gWa_SglYjMc-`EAA`|pC-n%Iw| z9Ell?Fa@O`smzg?!kXJ?t!lV#)xqDe1M18QgOBU%KYyFRiMrXj1b@-+>l&RTwrjug z{$h?~T!((OkK(>g@Tp6k8p+?oZ=0IlcBxK$5>FIxQ}#sy=riiZ{lQst40V;IirF4^ z2{0DYj5}x(oxG_De#@8%LD42wEyDO3Vt%x2+-v`yT zWb&l3rFQaM=EgG)`>?1a@@liyZZh#Cv{*9zHg<-5-DJGnO{}!d)m2z%2U7klTgIO7 z_)eT~pMm0pappMtMd56bK#tHMIX-N(L4DJd_cZF1qx26aP@eRxdsg*yY_SLVwHE7S z3@U@GLtV#ELji0`L1+$&>pLYHcFD<>vYntK`DnnZ93GL*`3X4Gn#$z zf)EK?dRAXVKX~YUmSr=PksnZH5>Ut15=r>A(=|EiiRh$JShd%+I_~d2oVUcW-Y|X> z=yermP@cq7x`5?-I4IA&_%5)RvfN*+#8}!^7GGqaDva*Je@ZXu39aQG29NGqA8x9t zyS@J_H21;x_4G4tUWG`Gq`R#Cp@0v;A80>92@$AZIYR1xM6v4xD%PqQMMj0XrKQe~ z0CP(r-*OKr-We}^LO+IvvUp_s`1m(z5%6~;5i?yxyYCH*!iIOH9Dgas(ELd3$9|5f=h}jUPVc`s>T$* zp{8c@`RaJ4O4>3p498>%a{#FJez_aswO2)|x=Jx$5Pd#9YzeXrxcVKD_??a%1-OA# zG-i?s=A`1KB~V`@OkdCv2fFRhEr)Xtc%#2+t~`i(LyOy=|JD7lg(SbdaSD8h#%J;D zTM6J3C=l|?mc6+4!CYoa`S-On-6Cd~k=U6tRk8ypDB$w->B3aW)bnzh6uUllN)gAxz&+%>jh2u#)Zb1kAeq4iKU^>7M z7C*ivMle#>0^A;y2nqduduR&xzUugiqYLXt z{nGb1(M%jSy^p?K&qSC+{~k*KGZjMcDRM{;RA$(1Mt_DlfM02-4}^C|IWVQ3uZL`| znmRR3CvIg>j?fOgZYmZ%xY{EFQ^I{!7c3A}qVcD}_C=s>FtUnW41L_Mf)T28|1#s< z?HVuX4NdA4q3w+;zG;J0XPIC7ccWBe$E9qI_FvE9)T1>;FRidJH=h%Pv>y!){5N8Q zo|QTcR)Fvq)YfLj-T3R{vaps;9X&HG~PTGAOQD4}lI+!VEn{T10y73lC(thUsWUd4j%Bx?4lX~^PtIuk* zqba1>!}G3EKuVv?vVGZ8`43q65d!xa0n_3{R45A5(?xMQnZ1%oENV{pDU5|P#Bfl_ zPDx3hn-V!)T(xoc%$QWa&-9viw=`D^$X^u{k32mfZWlj)uPZC>6cp=R{y;ygc0WP6 zknV1RY}ZwGz-k;h`%Ld)an&NQ#CbHFKP&tVh6d~l%in_ITq`gpOr=fjozu;;fw7sg zWboMAN2|zIMwJSt*g^?ph&G3)b1_>?f;9oE!Sd9oZy!Dw1eVtR<5EQ0x)ps>-0$Yr z=!F(A!OXDqEE^%)VBZ%h%rnNNZO7${dm zo-nv!*-1!7Mes_Ylq7yFW*kiL2_a;&8TfQ$5K^L#v)z$jsOLnn2xg3o)~s6zH-=vUWCGEwjTm{G!>bBAZ4B3 z3$NzD=m|z{A->AwimGM2qq$SwOWOra3}n;>&K$vRnP^8lQRp%-ltiUa8V1X_mdHPL z_I^>S%!r~;rng#5HKUezgQ-`1CQvJ!xL+wrtqaRV#CflYOA>{c<(24i9s^ITrnjIC z#J8CM2c+q1%)UW@n7v@Q6jW_*{z)X8w|agimftI9p{3@k@V39nX?taoyT6Fq@tx!M z>9{!@_Dxy|S>8W;+YrnQ%C%EE_Te!;#h`)G#DMuLr5l=D=k|;ueS#B=GFa2pMw7>5 zZa2d7NEL;4Ddm16n8M?=0z-!tkP51fgDOR5*|?Ac^i$qteP*~5*OSSKcPIjzg45vC ztF@b77QBTZ*URZ(Cs$5OW(KGKF%=UiK->EUx(=DA2}C?@8zxrW*(qj0(wt6a|8UhN zE+liJZ-QdaSmZmdAqMO}AJr56NgtV^C*S5}J0I^m;@kBUVpG%Q5vN)T{2if0W1z+p zhg>7Ou}6_=vOV{kVY}|$qWU||y{av$SH45?pS9))2WuBR)-W`UAe{#O$OYZ1vMv5`KWKZAiq^S?1t~C+mn>yU zCO=hTR4am@^=8JAkV7+*E9+F^D@g-@*f7 z`Z9}G(qNlf2}-NArjMw#ez)o;)}~1T22TX8MGL!G_qx#v`bN<`XQ+ZuDoA*2Q3{8C zPZhLUq#!7EU|jh7jc>)!_rBS^uz6P*l1)b}LJO-`iB&7I+e1}WLPv{)ia{wiR}cST z0SfjfH9MyF=uAFV(X%u;*&wYa9q-IP?U~Sn5(4_g>k$J;3aAn_bU$2oS_U7An;>?a z1AOF8wP~~=`pUb860GPHpBkYeQNeIqz3c*Q*)Sxo=u;~n(XH5w^kW+!csQxQJr7E{ zPnn7`KgEH)_d2}3n5!G1QQ0=6PObBRXO$)LqSk$>zlUmOKF1=-!^BKYVUvykoIZEw z4Hq+sQz@=tB{RZn+~Me^*(ei)BZ#No>T*`F_sE^pwfF?DFptdTe9JQ`H zsXtuzzTKzL07ncfF;D|LQmIOLoR4^PnO?H5FE4E>M?~iKAY$j%j8UBbUVWL|=Otd^ zrY4FFLhCsghn-n%li&9iM32qknJ zjZ@0Jys~_(%%y-w{>6MZ(4qGQsC}Ftz|NjA^EPupVDX@3nf2*>D-q_UVOB;dd8V%n z{Scq63dnZEx~WNG1|5x04|sj|F`vZ3TCQkQ(egN}RPNWNi3tnmYuXft=!i=;C6o9= zMn^&AZI*eKr-XX~E&SuD{%H1;eyN+1qdw*GL}}v2soaJq>z&1uv*sBy+4tn_(M>X* z0HF2}`|pj;gIl@boNLAV$GzsGo5Cy4MQ|`Rei{T(ZD>Ncg7HMMA>(}20YnkpE{0cr zY75Qi2o~8k?GYPUGo6SGCFGMJQbgEq$|f#0m4cPPAE$JF+u1}$K@AI)W}19araL7J zrjI)C=(Qp7Km2SbU-sT^-YJEoM_nSMx92!jh4r_{f={^~E03pe?J5Y9{gJ^;+T>`? zw!Ps|r|f82Fnu*5MW=cn_AVY)zGDVb@yh${dh%8@M5#Y+5AYiAoJ6OiGq+34xYiVx zFQ|aK?uRASy_NZJGD~KWS~M z=XX%rW;TZHR7B2%yS=B%)DY)6$*(XOR1WsvKONz56NEfZpoSVU1NK%Q zx0iMAdTunERiIm9#V+1>S!8DM0cvmml|LJMsa}fvzw+a7v7kp|-_@E_F9_N&=vrRF zfnJkOMfWsIA^Pk&%gS2a{q7A%bpC7HznuLrI`xRl;fBsfC6C|xpf23OQ_+yb6b-@}4DS39Nc_8l2e6#2%$-peo)0wA zHbvtsm_&v`m+4Sq z^n;5L<{7s4dk%g1A&qj&8_zi-LH5g6j|a&QQwS10@&wiTYyIWeKDRRHcptc zsLLD5lhv8dqD|Q{qW2Kw0i3`_aT^^-z$LRL9pIoPo24G-qHzvC-^6*j-h!?~(b@8$ zb;IFIr-K8y$kQfooeNoekse{e;%LT#hon+q%xMGQxIe`kvQ&yYfwO!_-mpT{9%915 zb5s*yb%<34kXV}Kqbtulv}I+tZ6+O8@D88#;AM)@HMGV=u=Rt|wY5eqTQ{uwfDm0{aM`36?&Gvc}zjx#46cR+NM#GF;VCjWqRTkw$S zv3uj5iu8BteAB;hiw9N-Q)|o~spjW+;0#{-F7<+FfkKsPpx48*cT#9evU&}+@{ad{ zl`_zy%^+<-a>44S?&^i)LN5X5Lbx)TM&Y}kX*|hOmA*ZUdTY$&`_6ba4}R84M3|$m zS4a_t$&J-fLuxDGNihjurez=KfD|gcv0fT)@tRo&a6^^?0R`76YADLUAYHySa ziO&mO6eOz&^8&tCcyk>n5;~$987DojjK3_(vzaIUwZrJhNtSco&GuTbb>`aSN0ETy zZ))rMgYWedJ5smDH=tU!rcCu0td(JQ*f@ts@oEp(fZE>*4=ZXzj<_G27noU` z96pcq$9_+xXF}gX79ULmP5>IF{GK^iMKvuu4ir|U$4EH_5XnQ z*|72EdmhiXeUEX5<$dZrsAmR9C^v|qj5UUeHmJ7jX+I}7#%*f$ar{6gg`&EdShfRj zu&!Gt*GjM0eepbpnryYeut|6Wck3h+k^z($Yj72My~^M+zdPVaKw3OwSyJsd+ySm& zvL-zp8|H4q7S7`)bwP4{R%~(rR%Vu(6?sRM^%t=i_QaZxmGrN$g48dd8uimlTSKK(LkvNRR|3+2v$Lj;^Y4bNqp1&t`t zHP*FC!-3d!R-2XudK@~XE44liZ!-_;A)s@4vtg-DowiaHs}>-@3I`>4L-^UT??eyo z>>_zBnn*v=t|4#9%D<*+(W%@S#a$U?$!r08BJY4DtMSNPW)3S~v|!bSxMa2W!i|o* zx5oO_rDU^|^Fm{xQ3Eq_sott-XQ3QgU8dwL)vxuCK$fW zkVNws4^xn*Dtg=k3d2rQXx+VT!HIjHRj$E=g_}DBL3HAbeL@s|>PPlc^it23ouYGy z+D*3w<-Ri#otx|D`?U`PFcL}am=Sh$&U_%ptzcj|+gtcflD^H5C3Fej9uIBoi$czq z-TS=}&eu!&r%RV^%Z9BVC@2L2dLHPccQ6ik-LFo$75(k+P96JMlJ~j!lYO0~cj(tx z<1ZCU`o2~~)S*lmK_a_0H*ShXg5bw~0a7Xgy@P3-q+wgkYjyf^;9R)sd@824pog7J z2)$clM9VTK1C_BXGfo!RyKO~F16e1xrh#%BT^Vl@T@Al~aMkonl64qXcg|?Cn%t1F zUQ=WLH=vW78_0NZG!5isYIQX8EifKxrNXfG9`mKc{yv>$u#hb}NQJGnqh&CXeTK6M z#dJZ|jXYWXm5SFrx25a*@UadH?=CJ{(g!DWMXZI?G!Wi8z34{4MgcSwo3nA1?zB{t zF9>F-jFm5DHXbal?^K&3ba(*N>$obT(z85FkJa!{92Z-cELZ@QrVPGyYgxeutn4V{hp3YiI;Ma@2h^2QLIikb6z&WT{-MvZa4sMmh; zNR_*joefIN)g(UruYFgXQmy0ey@^w$^asffQ7hZ#j3kQ!oide-q-crs(G@Ud<(!-# zqzLtLVI~z}nLp#c6>lL&F^9A!E>RaLOw7s?6=5d_X{i<(&JB-BcoOU$TU^iYl^&>^r0sF0THHot17Ilvb6D>@w;cZ6j;S8^&Q6&s# zM$SIQbuy6GC5&gNN^F?R73vhfJ6O)FCOD@Cfr^O2pTSsn(y~myDo0q=_!mHktTOwSmD9@b#;u$~ieDO&20j5C=9Q%j&a! z@XF0!R_nDw-d1ve=+)@6hBZ1IWo;#EX3pX{Gxk2wg@z52Ii?DYK9{q`1CIrZ4GZRW zm7gi)ByDqy=5`y=7pWJmD^{8pJJSHq((tbI2cl|Ob622>_c4O`iOPaSW2~Xe zx(ON^5A)fC%vzay7I|tc?UF#B#l|K5a<(PMu;sFll2EatHA^}jz>vjy46p(pnWGG7 z;&KM4_umX-LHummmH8}XPlY>r6laz)KW!dj*4cu4?riwD2qW$+Cz2`fuvPge4p z|G|slL1)_-Yk*PoQUqrp`ErTP64mk$b0A%_AhiptV0prTl_2kGg)q60N2TV42=wWV zC6oniAz3>R>EAltFgBb)V)KHgUldMXX$Fc`_V&VsNyDO9lVx%Uc7w`XBaX7G*-C?G z0RwZE%tTH4#9*~X6=$)b`-4n}`a`#3-PACjYE)v;GGD^7h1b8tHg&^?}9zAxUyh;TuVG-$-)( zM$)V}bLA$g)w&vrDUXBPgn7N(90MRK+IVFfW4``8dEvhO`#fUh!mA3laA}JUCdWpQ zZ&Pf*vGHDh48|)#(?)b}o2$VcvO&bDNMFP9xcsHOk$luZDAXDxhTm|WzHzfU%xwAK zvQgWiv39|1Jyx++ss0d%dRk#pcfrZJ9H z`&JPBg#Z2_nt$pn*iU#AM9tu)zr6G#ZfwsPp)T7{8lfx|JEX4&arY6H32rmCH#3e_ zZIr5+)cxr3iSjT>cgToU7auv-WCBQ7npu8FbJ|u|Zgo0W6fG=h${K4c4r}k311;6F zbXQuFLEp=OmJrUokS>B7fB_N z;dK?u_0F>Qf0JtrU_K|<$=LAp;W11TV4@Dq_X$Q=%`9O0Qt?=MwJ=TSW7R%Vn3_4T zbqy5(?~nFVF}4M05NQ~4An>u4>$WFdBlk}3LtR;1Bl~mI4{!VB@WF7-z+zH!XC&y; zwtq8{+0V7qE~2+<#{Z7Z39M2jEQS}dU-RC7*nW2Ep@^b;3ONE+#gfEsv+e9 zj%UkO%k<9u6J3!T97u1bn1HxqM}j9pGS7567!H1sQYszE)DX5MY%R!fjUt1IWz@Pm z0x!qU{V6hO4m`|T8RspDGhs8VD3#SFt+?`L2v_RaVU2O6R=ShcyJfX3`iVX^lOZT$)U>q4W1kI0w2RRkw^b|ZvZSWN($5}}l zlMKy1Nh_C$y7bs;LM#EdAWvb2L}|91bERQ)5jD>%*#aN!RW(l6JOaj1ZwCQRMevI{tST4HGI6)mjCB^~!6SiP_B+dz^q}%zMROlj zXnFI(3?a~?;&K2X*wHmbx@M*q+b)mcngU^mIS3k)M!hDn2l)+ONz+^GW5kJJN(;Mr zn%<6uTZVFfxd2J)hFfhs^x$=9>ifQuQ{7~1TF~)v&r9m#bcZlC>HW*(F&i~J#Y0D4 z!0DZGHe{I263j1Zdp`MmSfK}1eQ(xEgrMr0r8CZAe)9pLB8}&~5#`A6pnRd7< zCW+T}3GyBFtiz3%@65F9sk$~*5SF!K;BY>%ppq#(qibVR38|X$kelru1w^mz#Sudf6*|4TvW|A5>Za!PG=RhR1bv=+nvT40Pgm%20 z&D`5^B&71lLZ}l_sRiT3!{V5RT^m)4+;UXCVOG8Un;t}kB(8Gnm-dXT?=3(XC1mYw zzdI(kCC_&j2Q^2iD43mrU4NMw;)3JW&is3IS+YWldo?ljJ~A|JK6<{ziM6%be8Ymh zrwwD{$|)3*{WU~*tp|j%qZ<$lEWQq#=%$*P&cPV_fVgT4pLE=m`)3IboG|muXuBj~ zuCxwXQ!IDdhk7iiwrs?^M(lv$%^$h^EPt=4u7++-i_FkQSH!RlACba1me_yc)ES4t z6e_j#f^=2b5os1X1lcpDMeoEhAa3120vF}L?%&;WIqCyN!K#AW$-MYEQSg*j+)M&U z|DqS4d$-j{`F#EH74X&bRl)hr;2UI|%@)lSktSQZQ)i+mZhSCQZ(LOBNtpDFll+h2t`A1`l)ssxO4IDMQ8``!$V+i zbWcz=%dbyJ^yAFQ%vs))(3Z1Af5DRehiD)m^~yqsH-;UYZy2<&>Syqoy^v}=HYw;( z7u&r9$!j5&(xPqj)))EP)EI^w2>$ES*cAc?rglSW4w=SP@B$d}t_8|iz!v3Po)fQveGn& ztffDR=jY7!*4uX!k0q+ijR^vLyE?rN*V1%NLDd+A_|q59IHNhLA^Lf&zuX`C=nie; zkQ%SC{IBEbBJjKeDiS3i{GmGvmh!eCiV0TJO9Fr`pRbr#MGwlSW$;Gj*M@$+Mve3A z87P=W`-6e@)T@@<4Q#DU(zg1V;MAg>iq59U%kYx+CC~TU>SCWc$9Pw7;b%Hd*WZWd zCgXu9tA4Ztn>vic1P%Vx3{?m22&m4BI`EYJ75pd9FvgkHCKJvB@R(A8B+B z3k(*w(p~;t)2z8Fj|#Uk;)EYEAQ0Lh`8zWS2}ZAzODMzu_Q)4cX(P?vB1xCaQ761n z&d%gtY6+?e;AwBj9a2w%Wi&U0+Gr{bl51*)6qMm61QUeC%|qTH$yz2wEW!C>v@g^h zmu^-~`FmVX|EH|44636E+C4bI-5~^b4iMa3gS)!~4({&mdT;^+2$tZk;UK}?-5~^b zyXXDx_v2RG-L9VLneLt+TirFYwcAg3oS^5hJoA;o-l!ONRh>cUA57K|Rh)c0oGPh0 zp;NHgKiIrzLhS*r8$)}qrXpiT2A##w6~F0eNC&$2KCZC@YFLMbO!so7M9$IDS`mhJ z04V}#)`m=9tuTuAS3zo37;52<-{pq+K3^y&`Y?>aNnX&&-7%4??nb$;$>DYEFX3AJ z_m8R}9O`(4Fo|$Kx5C@NuY_HQ5YcSfuTu!Jcohc!4(%n*z;-&4ifW@XE5DExMRAIk zSkd-71K-*V{qwXp8bRr8ooH^|1qBK=4^^^W7?)U>B1V{C7}1sp;!<>imU;=`()yJ@ zhe_*-yvqC~{2-Z$@*jW}Hd=iY)v~1d8G!hX+)^{U zoZ4q8g-?o`F{eTc&9{|}a&%oWHLRcrop>Q?kJ3z!Tk>7^;hU(=xshp+_r2U0KI*sv z52}}qcxg4q2lIM9erk&9^1W0123wu@duq!`y1{^pD%Bzg`14Sra5%@CCDN;Q&HHbD$|JbGyQP^dQO*<3*3Zp{U zX_Z)E7R3k{BQ;DOaT-avOi&>vPw)VdYmbx8`b)n(C*f_M;OzhH%zxJH4vU|#(`6so z5iZt_{Xwf6+VK5|0r{|eT8^>qeH+Ol`dIgKAMQ!Q!aZiJl&)AHI1hhqi|Eub$y*P5 z122`R55A{#RhzmKlYp9VDew16nNLtOAua3#UfV1aV}ym$F>N27WblCh41cVqhhDEaamde!|1tU)De+HYAG)&JDuk$F7XYuySytl0!%jk+A*gO~8EEoIRh4}i4`DzO>b|wc5{S*xPg3EZ;GUAn zzJW->p=6l?Wv!1;ro=Bv>EK4$8Bc~RpW#)*kEMxM?~fRcS4qoBS$dMWgms}G|A#L^ zI?g`hOX>9{b2wF_!y}=+e}@gn|IEoR z;C&3DuJjmjhp{@7>x46*z7%J$5sH4IagfVAQ+~8WQoXFA<7Y_U66?Q;pyiq3%*;S? z%U#<-AQN{;BZU&4h_`_O_=%^jkCSfwzs;#_?iwYlO=eLm$TbXh0$oP!9?`5eQ_(TG zid>c!bst67>mdMR#eT%;*Y+GD0*|WNvc!X{+^LxUt^Rr%$QMpHoW*Hc!mR7NgfH*M ziQN5y)cJXv+>Kr&bW77o>$_dR`5=<_NA4n6XTa0!R#qOret$wU>Q)_5DO>iGDZ4Ss z`7JPhykq)J2Zyq4r#;jWn@Wkljneb~V63B~Tq|GOjV|Ec@M~%N8^7RshBpc2rr#nugGO6STcPFw77n z2HR1*KJce(&}ran>~~*Ud-MKHjQ)T-T8Pe3-Zp@u{e5_!Xr2Y-N}sRz6@R9wKmWlEETGx^B$3l?h z87uvd#pbs^?5~GSSg2CNX;%?CB_+}6?A%hzGJqMGIzC_Z&*z<=v_jNe>Sh!_111yW z@=}DU>5VmG^JRB`Ckdm#;nKMg!Bblva*)66aeRFHTQtH#WR|z_c*o&&QEuxslI4>4 z%Jb+zVp8Z^>PdgSy!)g7n(34=i#k{oqL#}}$MDx8FfNgtUUw@&^cKSy5rU5X5jmds zZJu{ zCLByzlW8$PDltl4xTJxF`8`=*Mxw7_H{A)Xfc6nrNID9ZB5`B&SJ4%_h@ho`Uh_gd zmr@~TKCV6$JpwJspE|ff6&HUhL)Yu&Xce^wu|?hU>lf@337&7Em$#PME0U_xQOclEV*h!QMd{+HVOwzJdXO0MWMzgm4uDuzy_<7hWk|7Oee5rqJ z9b`ysG5RUykPCKE3+b&)UGx3p7A#m)uM&nm{E?x$wO$*ZRzzyMJ4W#XhRmio0-=1r zLc!q8BJsxIC4VbLTebRVrgRWY0XfoFZyFDon6HECg00_yrI_)9(3gFg*lVK~`41yD zz#Uv#OGvEAUBH(U`u;}UNbN^GoO#Ha9?bMOrky8HYN4TYu3SZ)r3coEfZec+U696X zJia2ZtzO)}lv}@8+$DBY3zyNmEyq1Ovr6$vr*kk0XKM7A=~BZ#Fst4k9|5zUXF`Mv ztX`$gX#GCt`n~mvL{w#@^wk+~kRN5m(zhuD#}Y+pxO+W-{67nfy4m&w@0L9LW$7Co z0cKTEVf$R>Y~tD^sQ01$<)<6i-pM{aWoB)n->TY$*#0AQGgKBeXeJTu{C*g>Rhia_ z770PkIv%^WezENQqlK+w)|S(#e95$#R?ToM3H`dZI&g?0#P1u|uhHk0-i8+@W&yGb zEEalOjBGey*&Uuzz$mb`T!J@Tk?-JcoeSb*J4xy2U@GkPQaOnyx`_D$N49xH`rrN+ z5tVRTA8tnk+FCN}xlufGFPkK|mOX4iAr=wdI!Z!xu*3K2$uL%>f=MDZZ#9Z z$99g*z<4{Ac*uH{l(Dqj1x_+cAV9JT(Jd${3$~iaKW)x=h_~#y{}F4i2(9Iiswk;Q zD4nA@w&if_%a!m$I4P)qsF5E0TDZxYgobsC4Y0^-#x+%fV6(dZX1vUH5j8(CUFFFB zg_^eZMb@@EpY0<@Sx1ydyUAa-hOS@%4+K!^dc4FcAYD(e^|J8hC0YIh)kw8+jyuWX z>3FWrv^1Rg(|vNiKRv(<0+SXfh|LXtK9yUl#yLY>`Te0|CGV`Sk>2|xPvscc!!hCb zXX;-sW*No-Y}$t`V8(hM-}?a(Hka?!jUN5Y;CkE-RPRQ99!XLS**Uu9ak;g$b+y?_ z5!pyZ}*KKFaBkA{@$bEf{YGPi`atLv9?jHwlCkV;s7d{fP4{tmrExN#%riL`x&R-P|a zy$7dF#TX=hC=#DvTabcd*~`Umqf)ccvK|#VO`hv2mnKAu-Ms#wxCXvrPd#Wta*bAe z_Gz-lNrn7#o&ueN_6Q`p4?U1N6nGsska;XpG)X0hy9OFCt%p~He}4jCr#-e(+X@zr zp)}Q)c(Su76QNV!nO4Cuf(0zNnN1aPZbht=2n>=qSp7CTD=uU3l@!cY@HHx{B=t0@ z4j?)Sl|GMOPOY^eHoxi4$P6>aEImbQ!G_Iqyl?v6GWmH-Ywk>h^%d<>>3%fPWozC+ zgk_0uF&}1uZ435JMnsV#to=h=iGB}`E*_%X7<0#ST28qQ7_+I-{I3#oLqUSh?+wrpVRc}I{)Un^ZVkabiIC!z=m}L^cXtwoi`n6 zhF|_DFPgF*S#x@<@}5t)mI0*_9`HgCl!e!oGH6My_YI__-$le>)U+ zv@5sS9&=$Y8(a6QUAb8pY5bA z))r>#q8ZuQlIp~9Q`g-ZE9zmd7*Nb5^l8#O`rHaIPF+ZB6cub|f+po4WfaW2ePC8A z+=te-I8D65A<}k=I%aMzptVwnKFQIahau`r=t0CPh)5EW6q1YhQaVb!zwYTxGt9Ru zZnBTPwH%&t7gf7i-Vw(kVY@Tli+M9M#^N4ocW&BYH%y*%!VL~6_{{e00Da}#8mI+z z&F7c{N8`NxCzj9JIb#^uPk2#^DyNjFnO2YGzUTRBG;YBEaIpKLOwGJ*pyi{ip(RHF z4OY0U>xs1UAGxqzV<9i0YlRZL^7=UunKp|rdVt0y?Pm6P6S4dfgr2CB4IXC2ulW6=8i85D%;^w6m zgK;}xaN(TV(uJn=ICuaW_pRs+lNu(gU;3Xz32!}x=RB*Fki0<+&E*zD2c*>$y3U;e zi*nEZ7Q%=0cE&4!pR4X<3~PUQ^Vyu7vBZ=y-dfuZqsKJ-Wmb{_v{3?o9$&U81HhwN zK^zJgsV@ei3zS~WG0a5I0qDImp8Z3k)MUdN5`ogV=sJ}<04clk|OUv+6G!Us)TI(n&K6$ z?51}{b=UrV(|q{kM{eDtwU4;+dNS6mw>sOnJ5pzAoJr)EeGWv0;9{L@3{sx_lIYmw zM+sbF?R!mi<@N7%^zG09!E$yNiJSU0LAv?$9fTl`=YqQYbW5-9fveSLA6A-RM;3R! zc+ZK4^zOx1LD+v6C%!It7&J1q?Xuj!h-1V2LuND}VMS1*|QvzY0Zouh|&U>QcyA|BQ@~1l^a2{&H_9@n%Br~p9P|xw?cDIT zh!YfGdBKz38kIrsXyXC$omN3DpR|gexZhtF9q1|E9G8GK_3ENDQY@Sr8!r=T*@j@Q z233G0$odp~2gij`&)5Q9I!7=}jrdgSy(g%VBSI-TvKt^FftS}|;b;M|<)sxp$`2w@m^W%6`jeyhukU;-;1Ib%e+gV5*V#a=eJu&rW-Wb_%_?C?uolBU&DWxZ1h z2_GG9UVo}(nrD%r>C2JvKmr&(C%&wP_0fKThno(%&r~Y51SutRIAYPL={`BkLms!L zgMvtutQ7mUxLy)ArBi~OgDxIhYVy{3;!guB&*L(~re8ylg;tITu-;ajl2MQvcJ^_#kCY4{l-D6+cI$s(ov4zqNfg)HwQ_~2heQnRxn z1yzNd7weiC6*y!%zjr8n)2UDe2R{E4sxme1pE>!fbHzI*1kv*IsekC`BzvJ^-|7Xe zt}2NudhB(_I{!BGeGu=!q@BOqcdpYV+p#&oXrM9ugwYGS`ZdqfwD<{hgOu>dP+TM< z%cvm6T5)3DI*m~Cd=qWvl?<8&G#`A+dry*l-_^z`sm&knT5qgIE0+Vk94g%*w)R0wX zUa|ttI)Lvr`42&oDq>%xR$WXlj@aURV&1$mbYy1AYS~bTj&o%^id*Pgo)=`Ny*t)t zp_l^fU(0RI!Cyzt7Vc$26SekQ|%a4feOrTfd|{IKi%X>67j`8gXL znTPPv8@+B4R^;YgR~N$S$q@2uPRLitlG+j!Psga)=aVE)p$M%{<6XZfQRlWX&UVi6 z1-pX~(>AG)rvl7hE{6*yrwgqVRPx8Z64_Py<_!f;gm0kvRr>>e@u^VR*|0u2ON(t< zLt||=88L}RNMDKB<7I!)Uo;t0H77oqMVYF+DMG9feFa-WHCI;ilRC-#-Q*}3v5!Li zCz`FxqH%3RHSX%TjEZzd&CQo=h~vNBn!RZ8ckdHIeZCX;visw!HJ z0YylKtx@^_w&sUh4uLj#u7t-)NF?|D-qGIP#Szgv%AARjE#3>-F+kT8SG=Lt8%hw^&;DVz-7;_2_wU9m7; z^L8Grniy!!Nn+yLb;0iC(J4*p`KcvFj2ZHP+7cD4)E0zvk7kx1w^1Zl||fB>dQ?r z+kUXcqEw$*b}f$apY*V~)cj@2X-MjJ`c2}OzEY&33zB$EbZ07gQnAhn1)v^pkvM{| zf20Q-VOoT|A*BaYm;1L1=xyQOz4;gW?V8c_^M`!B#s~kRjA;KRP3jZAN#w#l@o0?K z;n8HIKRyV!Ne4|-0uiqFYCs52gm4x@Q`y-Au`=xbxky~t5rMrH8Y}u8opSN>g&IZU zLvMyMV${LS#nI#T$aGXmiPL`1`zldk+h)tieG((4xAcuy$+mAvN8Z5#$=X+oj}%M<+{)_OR>_R0fIE|qL7LPLT5N_R!U7Z&=t)fZMIBrs_3ghfie9*rM)^pVt;-UY z`f_579=mP~+7@q9z@knrTkZvgRYt@8)T2QrZl64k&8>~J8qJw%M!DOA_c_}H186Pg zX*k7jP zy$rowlg&>5Pwe!9Rpk#CrWA%V>6JXYQ1d`_{#lmIrN4oddBz0TY4|*I%7D=|esT)T zBpuxrkg_FZ1%9aJeoUJS4@N7vZm+Xg?Cj;+Uxat?#Qw{+^vhL*TpB}Ow-ou)S)AG% z{0b>P^U}iyhStxiksde*;*DbD!q!_>-*z&iq#L*A!|*F(Ox|!L_TQg|M8&Pl534Pm zja6+BwSw*yIhFxEUo#WFCsA5BpS)8Ub1L8t%D4e1S%~d;;;_|UqS8w8W)2qiy8%NOFOz~b`O+$!OKJ_E1dCKh!Z z`)TSUZo(1|yY2b;PyKBPoKmP$Q?X94u%gN=*mn2Io_}KFc>9GN_o5hJu%+p7yplCw z-z0W$^YS-RnQt!Qg*#$qMq(_ZS|`6)Y^$pjR!Uf63V=zKFV1>fnyTK zjIU0EroNgJH=XcQi>u5YEXO}^?=tu}fX_|t$A=6B?qpVW2!}M+@5Z8m+LbKf_yfh2 zPv#EnNT)nuonLkrRyEMgg)LCsR@y7d8(&aG3I(Vx6&&P`%q!-|jp_4sG=Dz2e!myU zk&#Gb!RalObm4l1AS}+R*r?uLmtPWk=W#SvL#{_N168}Sv7Jl~76f0kwi81#x!q=!q<)A9dtjDn4`6!9GWX+@dp8|PXm1igM5yo4GW>#(fHgnVSyit(msWkH_O{DwK{*RJ++3q9H_2% zou>R*^hepFJoNabuXsHRm1@c!?Vysj;&lU5sw#WbgG$DV*Vj<#XW3($@c8YsZgXqu zKHyoeH#OaG=#n0>6#;Yb&xwrS2MKHO0;K=iVG!u=}Uu z#?aC$3p;KHD>lLH7&&&Wix)$qvT~kk@{fHzoMdfSo!J_-JY)YfW~wc^g@# znS|^{YiJw^sg?3gAGbY|V&^4v&O_WV@-aDQs^Dn--LzWs+8Sf_w@%iVpJkcHnB5fL z+bma&Knu)H21Xy2@QfHqb(CDMtB8_$FGvLL-(gf0VPNq9cmMzZ86Xo-po?mH&o6)q z0PG3@0EE!d|1KB+<^Qw*fQ74-nY)#ios^Zeoui$*os%QmS2rie|JR8J)QOYEtt@sn v0KoGP9)SJ7rvKN86Vx@x%+68M3gqknb@jjI2#Eh_!9wqFX#2DDKk5GfhQfcB diff --git a/Solutions/Jamf Protect/Package/createUiDefinition.json b/Solutions/Jamf Protect/Package/createUiDefinition.json index 5ccb070d126..9b0ece53e37 100644 --- a/Solutions/Jamf Protect/Package/createUiDefinition.json +++ b/Solutions/Jamf Protect/Package/createUiDefinition.json @@ -6,7 +6,7 @@ "config": { "isWizard": false, "basics": { - "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/Jamf%20Protect/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Jamf Protect](https://www.jamf.com/solutions/threat-prevention-remediation/) solution for Microsoft Sentinel enables you to ingest [Jamf Protect events](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html#task-4227) forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.\n\n**Data Connectors:** 1, **Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 3, **Hunting Queries:** 7, **Playbooks:** 3\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/Jamf%20Protect/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nThe [Jamf Protect](https://www.jamf.com/solutions/threat-prevention-remediation/) solution for Microsoft Sentinel enables you to ingest [Jamf Protect events](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html#task-4227) forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.\n\n**Data Connectors:** 2, **Parsers:** 1, **Workbooks:** 1, **Analytic Rules:** 3, **Hunting Queries:** 7, **Playbooks:** 3\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", "subscription": { "resourceProviders": [ "Microsoft.OperationsManagement/solutions", @@ -64,10 +64,10 @@ } }, { - "name": "dataconnectors-parser-text", + "name": "dataconnectors2-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." + "text": "This Solution installs the data connector for Jamf Protect. You can get Jamf Protect data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." } }, { diff --git a/Solutions/Jamf Protect/Package/mainTemplate.json b/Solutions/Jamf Protect/Package/mainTemplate.json index 4b2df75e1c5..63fec43f380 100644 --- a/Solutions/Jamf Protect/Package/mainTemplate.json +++ b/Solutions/Jamf Protect/Package/mainTemplate.json @@ -28,6 +28,20 @@ "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" } }, + "resourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "resource group name where Microsoft Sentinel is setup" + } + }, + "subscription": { + "type": "string", + "defaultValue": "[last(split(subscription().id, '/'))]", + "metadata": { + "description": "subscription id where Microsoft Sentinel is setup" + } + }, "workbook1-name": { "type": "string", "defaultValue": "Jamf Protect Workbook", @@ -53,11 +67,18 @@ "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]", "dataConnectorVersion1": "3.1.0", "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]", + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "dataConnectorCCPVersion": "1.0.0", + "_dataConnectorContentIdConnectorDefinition2": "JamfProtectPush", + "dataConnectorTemplateNameConnectorDefinition2": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnectorDefinition2')))]", + "_dataConnectorContentIdConnections2": "JamfProtectPushConnections", + "dataConnectorTemplateNameConnections2": "[concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentIdConnections2')))]", + "blanks": "[replace('b', 'b', '')]", "parserObject1": { "_parserName1": "[concat(parameters('workspace'),'/','JamfProtect')]", "_parserId1": "[resourceId('Microsoft.OperationalInsights/workspaces/savedSearches', parameters('workspace'), 'JamfProtect')]", "parserTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-pr-',uniquestring('JamfProtect-Parser')))]", - "parserVersion1": "3.1.0", + "parserVersion1": "3.2.0", "parserContentId1": "JamfProtect-Parser" }, "workbookVersion1": "2.0.0", @@ -65,7 +86,6 @@ "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]", "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]", "_workbookContentId1": "[variables('workbookContentId1')]", - "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]", "analyticRuleObject1": { "analyticRuleVersion1": "1.0.5", @@ -75,11 +95,11 @@ "_analyticRulecontentProductId1": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','6098daa0-f05e-44d5-b5a0-913e63ba3179','-', '1.0.5')))]" }, "analyticRuleObject2": { - "analyticRuleVersion2": "1.0.3", + "analyticRuleVersion2": "1.0.4", "_analyticRulecontentId2": "44da53c3-f3b0-4b70-afff-f79275cb9442", "analyticRuleId2": "[resourceId('Microsoft.SecurityInsights/AlertRuleTemplates', '44da53c3-f3b0-4b70-afff-f79275cb9442')]", "analyticRuleTemplateSpecName2": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-ar-',uniquestring('44da53c3-f3b0-4b70-afff-f79275cb9442')))]", - "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','44da53c3-f3b0-4b70-afff-f79275cb9442','-', '1.0.3')))]" + "_analyticRulecontentProductId2": "[concat(take(variables('_solutionId'),50),'-','ar','-', uniqueString(concat(variables('_solutionId'),'-','AnalyticsRule','-','44da53c3-f3b0-4b70-afff-f79275cb9442','-', '1.0.4')))]" }, "analyticRuleObject3": { "analyticRuleVersion3": "1.0.2", @@ -285,12 +305,1395 @@ "name": "Thijs Xhaflaire", "email": "[variables('_email')]" }, - "support": { - "name": "Jamf Software, LLC", - "email": "support@jamf.com", - "tier": "Partner", - "link": "https://www.jamf.com/support/" - } + "support": { + "name": "Jamf Software, LLC", + "email": "support@jamf.com", + "tier": "Partner", + "link": "https://www.jamf.com/support/" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_dataConnectorContentId1')]", + "contentKind": "DataConnector", + "displayName": "Jamf Protect", + "contentProductId": "[variables('_dataConnectorcontentProductId1')]", + "id": "[variables('_dataConnectorcontentProductId1')]", + "version": "[variables('dataConnectorVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", + "dependsOn": [ + "[variables('_dataConnectorId1')]" + ], + "location": "[parameters('workspace-location')]", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "contentId": "[variables('_dataConnectorContentId1')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersion1')]", + "source": { + "kind": "Solution", + "name": "Jamf Protect", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Thijs Xhaflaire", + "email": "[variables('_email')]" + }, + "support": { + "name": "Jamf Software, LLC", + "email": "support@jamf.com", + "tier": "Partner", + "link": "https://www.jamf.com/support/" + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", + "apiVersion": "2021-03-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "GenericUI", + "properties": { + "connectorUiConfig": { + "title": "Jamf Protect", + "publisher": "Jamf", + "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.", + "graphQueries": [ + { + "metricName": "Total Activities data received", + "legend": "jamfprotect_CL", + "baseQuery": "jamfprotect_CL" + } + ], + "dataTypes": [ + { + "name": "jamfprotect_CL", + "lastDataReceivedQuery": "jamfprotect_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "jamfprotect_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)" + ] + } + ], + "sampleQueries": [ + { + "description": "Jamf Protect - All events.", + "query": "jamfprotect_CL\n | sort by TimeGenerated desc" + }, + { + "description": "Jamf Protect - All active endpoints.", + "query": "jamfprotect_CL\n | where notempty(input_host_hostname_s) | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | sort by Event desc" + }, + { + "description": "Jamf Protect - Top 10 endpoints with Alerts", + "query": "jamfprotect_CL\n | where topicType_s == 'alert' and notempty(input_eventType_s) and notempty(input_host_hostname_s)\n | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | top 10 by Event" + } + ], + "availability": { + "status": 1, + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ] + }, + "instructionSteps": [ + { + "description": "This connector reads data from the jamfprotect_CL table created by Jamf Protect in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API." + } + ], + "id": "[variables('_uiConfigId1')]" + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnectorDefinition2'), variables('dataConnectorCCPVersion'))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition2')]", + "displayName": "Jamf Protect Push Connector", + "contentKind": "DataConnector", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorCCPVersion')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition2'))]", + "apiVersion": "2022-09-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions", + "location": "[parameters('workspace-location')]", + "kind": "Customizable", + "properties": { + "connectorUiConfig": { + "id": "JamfProtectPush", + "title": "Jamf Protect Push Connector", + "publisher": "Jamf", + "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.", + "graphQueries": [ + { + "metricName": "Telemetry", + "legend": "jamfprotecttelemetryv2_CL", + "baseQuery": "jamfprotecttelemetryv2_CL" + }, + { + "metricName": "Unified Logs", + "legend": "jamfprotectunifiedlogs_CL", + "baseQuery": "jamfprotectunifiedlogs_CL" + }, + { + "metricName": "Telemetry (Legacy)", + "legend": "jamfprotecttelemetryv1_CL", + "baseQuery": "jamfprotecttelemetryv1_CL" + }, + { + "metricName": "Alerts", + "legend": "jamfprotectalerts_CL", + "baseQuery": "jamfprotectalerts_CL" + } + ], + "sampleQueries": [ + { + "description": "Jamf Protect - All Alerts", + "query": "jamfprotectalerts_CL\n | sort by TimeGenerated desc" + }, + { + "description": "Jamf Protect - All Telemetry events", + "query": "jamfprotecttelemetry_CL\n | sort by TimeGenerated desc" + } + ], + "dataTypes": [ + { + "name": "jamfprotecttelemetryv2_CL", + "lastDataReceivedQuery": "jamfprotecttelemetryv2_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "jamfprotectunifiedlogs_CL", + "lastDataReceivedQuery": "jamfprotectunifiedlogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "jamfprotecttelemetryv1_CL", + "lastDataReceivedQuery": "jamfprotecttelemetryv1_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "jamfprotectalerts_CL", + "lastDataReceivedQuery": "jamfprotectalerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "IsConnectedQuery", + "value": [ + "jamfprotecttelemetryv2_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)", + "jamfprotectunifiedlogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)", + "jamfprotecttelemetryv1_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)", + "jamfprotectalerts_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)" + ] + } + ], + "availability": { + "status": 1 + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + } + ], + "customs": [ + { + "name": "Microsoft Entra", + "description": "Permission to create an app registration in Microsoft Entra ID. Typically requires Entra ID Application Developer role or higher." + }, + { + "name": "Microsoft Azure", + "description": "Permission to assign Monitoring Metrics Publisher role on data collection rule (DCR). Typically requires Azure RBAC Owner or User Access Administrator role" + } + ] + }, + "instructionSteps": [ + { + "title": "1. Create ARM Resources and Provide the Required Permissions", + "description": "This connector reads data from the tables that Jamf Protect uses in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API.", + "instructions": [ + { + "type": "Markdown", + "parameters": { + "content": "#### Automated Configuration and Secure Data Ingestion with Entra Application \nClicking on \"Connect\" will trigger the creation of Log Analytics tables and a Data Collection Rule (DCR). \nIt will then create an Entra application, link the DCR to it, and set the entered secret in the application. This setup enables data to be sent securely to the DCR using an Entra token." + } + }, + { + "parameters": { + "label": "Deploy Jamf Protect connector resources", + "applicationDisplayName": "Jamf Protect Connector Application" + }, + "type": "DeployPushConnectorButton" + } + ] + }, + { + "title": "2. Push your logs into the workspace", + "description": "Use the following parameters to configure the your machine to send the logs to the workspace.", + "instructions": [ + { + "parameters": { + "label": "Tenant ID (Directory ID)", + "fillWith": [ + "TenantId" + ] + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Entra Application ID", + "fillWith": [ + "ApplicationId" + ], + "placeholder": "Deploy push connector to get the Application ID" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Entra Application Secret", + "fillWith": [ + "ApplicationSecret" + ], + "placeholder": "Deploy push connector to get the Application Secret" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "DCE Uri", + "fillWith": [ + "DataCollectionEndpoint" + ], + "placeholder": "Deploy push connector to get the DCR Uri" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "DCR Immutable ID", + "fillWith": [ + "DataCollectionRuleId" + ], + "placeholder": "Deploy push connector to get the DCR ID" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Telemetry Stream ID", + "value": "Custom-jamfprotecttelemetryv1_CL" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Unified Logs Stream ID", + "value": "Custom-jamfprotectunifiedlogs_CL" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Telemetry (Legacy) Stream ID", + "value": "Custom-jamfprotecttelemetryv2_CL" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Alerts Stream ID", + "value": "Custom-jamfprotectalerts_CL" + }, + "type": "CopyableLabel" + } + ] + } + ] + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition2')))]", + "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition2'))]", + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition2')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorCCPVersion')]", + "source": { + "sourceId": "[variables('_solutionId')]", + "name": "[variables('_solutionName')]", + "kind": "Solution" + }, + "author": { + "name": "Thijs Xhaflaire", + "email": "[variables('_email')]" + }, + "support": { + "name": "Jamf Software, LLC", + "email": "support@jamf.com", + "tier": "Partner", + "link": "https://www.jamf.com/support/" + }, + "dependencies": { + "criteria": [ + { + "version": "[variables('dataConnectorCCPVersion')]", + "contentId": "[variables('_dataConnectorContentIdConnections2')]", + "kind": "ResourcesDataConnector" + } + ] + } + } + }, + { + "name": "JamfProtectCustomDCR", + "apiVersion": "2022-06-01", + "type": "Microsoft.Insights/dataCollectionRules", + "location": "[parameters('workspace-location')]", + "kind": "[variables('blanks')]", + "properties": { + "streamDeclarations": { + "Custom-jamfprotecttelemetryv2": { + "columns": [ + { + "name": "action", + "type": "dynamic" + }, + { + "name": "action_type", + "type": "int" + }, + { + "name": "deadline", + "type": "int" + }, + { + "name": "event", + "type": "dynamic" + }, + { + "name": "event_type", + "type": "int" + }, + { + "name": "glob_seq_num", + "type": "int" + }, + { + "name": "host", + "type": "dynamic" + }, + { + "name": "mach_time", + "type": "long" + }, + { + "name": "metadata", + "type": "dynamic" + }, + { + "name": "process", + "type": "dynamic" + }, + { + "name": "seq_num", + "type": "int" + }, + { + "name": "thread", + "type": "dynamic" + }, + { + "name": "time", + "type": "datetime" + }, + { + "name": "uuid", + "type": "string" + }, + { + "name": "version", + "type": "int" + } + ] + }, + "Custom-jamfprotectunifiedlogs": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "caid", + "type": "string" + }, + { + "name": "certid", + "type": "string" + }, + { + "name": "input", + "type": "dynamic" + } + ] + }, + "Custom-jamfprotecttelemetryv1": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "arguments", + "type": "dynamic" + }, + { + "name": "exec_chain", + "type": "dynamic" + }, + { + "name": "header", + "type": "dynamic" + }, + { + "name": "host_info", + "type": "dynamic" + }, + { + "name": "key", + "type": "string" + }, + { + "name": "return", + "type": "dynamic" + }, + { + "name": "subject", + "type": "dynamic" + }, + { + "name": "identity", + "type": "dynamic" + }, + { + "name": "texts", + "type": "string" + }, + { + "name": "metrics", + "type": "dynamic" + }, + { + "name": "page_info", + "type": "dynamic" + }, + { + "name": "attributes", + "type": "dynamic" + }, + { + "name": "exec_chain_child", + "type": "dynamic" + }, + { + "name": "path", + "type": "dynamic" + }, + { + "name": "_event_score", + "type": "int" + }, + { + "name": "contents", + "type": "string" + }, + { + "name": "file", + "type": "dynamic" + }, + { + "name": "socket_inet", + "type": "dynamic" + }, + { + "name": "exit", + "type": "dynamic" + }, + { + "name": "exec_args", + "type": "dynamic" + }, + { + "name": "exec_env", + "type": "dynamic" + }, + { + "name": "exec_chain_parent", + "type": "dynamic" + }, + { + "name": "architecture", + "type": "string" + }, + { + "name": "bios_firmware_versions", + "type": "dynamic" + }, + { + "name": "process", + "type": "dynamic" + }, + { + "name": "rateLimitingSeconds", + "type": "int" + } + ] + }, + "Custom-jamfprotectalerts": { + "columns": [ + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "caid", + "type": "string" + }, + { + "name": "certid", + "type": "string" + }, + { + "name": "input", + "type": "dynamic" + } + ] + } + }, + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "[variables('workspaceResourceId')]", + "name": "clv2ws1" + } + ] + }, + "dataFlows": [ + { + "streams": [ + "Custom-jamfprotecttelemetryv2" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = metadata.vendor,\n EventProduct = metadata.product,\n EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = host.protectVersion,\n EventSeverity = \"Informational\",\n //\n // Jamf Protect - Device Hostnames\n TargetHostname = host.hostname,\n DvcHostname = host.hostname,\n DvcSerial = host.serial,\n DvcIpAddr = host.ips,\n DvcId = host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = host.os,\n SrcDeviceType = \"Computer\"\n| project-rename\n TimeGenerated = ['time'],\n EventOriginalUid = uuid,\n EventOriginalType = event_type,\n EventCount = glob_seq_num\n| project-away\n metadata,\n host,\n seq_num,\n version,\n deadline,\n mach_time,\n action_type\n\n", + "outputStream": "Custom-jamfprotecttelemetryv2_CL" + }, + { + "streams": [ + "Custom-jamfprotectunifiedlogs" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = \"Jamf\",\n EventProduct = \"Unified Log Stream\",\n // EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = input.host.protectVersion,\n EventSeverity = case(input.match.severity == 0, \"Informational\", input.match.severity == 1, \"Low\", input.match.severity == 2, \"Medium\", input.match.severity == 3, \"High\", \"Informational\"),\n EventOriginalType = input.eventType,\n EventOriginalUid = input.match.uuid,\n EventType = \"UnifiedLog\",\n EventResult = case(input.match.actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventMessage = input.match.event.name,\n EventResultMessage = input.match.event.composedMessage,\n // EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", input.match.uuid),\n // //\n // // Jamf Protect - Device Hostnames\n TargetHostname = input.host.hostname,\n DvcHostname = input.host.hostname,\n DvcSerial = input.host.serial,\n DvcIpAddr = input.host.ips,\n DvcId = input.host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = input.host.os,\n SrcDeviceType = \"Computer\",\n // Jamf Protect - Event Details\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = \"Create\",\n ProcessEventSubType = \"Exec\",\n TargetProcessName = tostring(input.match.event.process),\n TargetProcessId = toreal(input.match.event.processIdentifier),\n TargetProcessGuid = tostring(input.match.event.uuid),\n TargetProcessCommandLine = input.match.event.process.args,\n TargetProcessCurrentDirectory = input.match.event.processImagePath\n| project-away\n caid,\n certid\n\n", + "outputStream": "Custom-jamfprotectunifiedlogs_CL" + }, + { + "streams": [ + "Custom-jamfprotecttelemetryv1" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n// ASIM - Common Fields\n| extend EventVendor = 'Jamf'\n| extend EventProduct = 'Device Telemetry Stream'\n// Data Field Normalization\n| extend\n EventSeverity = \"Informational\",\n //\n // Jamf Protect Telemetry - Endpoint Information\n //\n TargetModel = metrics.hw_model,\n DvcOsVersion = host_info.osversion,\n TargetHostname = host_info.host_name,\n DvcHostname = host_info.host_name,\n DvcId = host_info.host_uuid,\n // Jamf Protect - Event Types\n EventType = case(\n header.event_name == \"AUE_add_to_group\",\n \"UserAddedToGroup\",\n header.event_name == \"AUE_AUDITCTL\",\n \"AuditEvent\",\n header.event_name == \"AUE_AUDITON_SPOLICY\",\n \"AuditEvent\",\n header.event_name == \"AUE_auth_user\",\n \"Elevate\",\n header.event_name == \"AUE_BIND\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_BIOS_FIRMWARE_VERSIONS\",\n \"SystemInformation\",\n header.event_name == \"AUE_CHDIR\",\n \"FolderMoved\",\n header.event_name == \"AUE_CHROOT\",\n \"FolderModified\",\n header.event_name == \"AUE_CONNECT\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_create_group\",\n \"GroupCreated\",\n header.event_name == \"AUE_create_user\",\n \"UserCreated\",\n header.event_name == \"AUE_delete_group\",\n \"GroupDeleted\",\n header.event_name == \"AUE_delete_user\",\n \"UserDeleted\",\n header.event_name == \"AUE_EXECVE\",\n \"ProcessCreated\",\n header.event_name == \"AUE_EXIT\",\n \"ProcessTerminated\",\n header.event_name == \"AUE_FORK\",\n \"ProcessCreated\",\n header.event_name == \"AUE_GETAUID\",\n \"\",\n header.event_name == \"AUE_KILL\",\n \"ProcessTerminated\",\n header.event_name == \"AUE_LISTEN\",\n \"EndpointNetworkSession\",\n header.event_name == \"AUE_logout\",\n \"Logoff\",\n header.event_name == \"AUE_lw_login\",\n \"Logon\",\n header.event_name == \"AUE_MAC_SET_PROC\",\n \"AuditEvent\",\n header.event_name == \"AUE_modify_group\",\n \"GroupModified\",\n header.event_name == \"AUE_modify_password\",\n \"PasswordChanged\",\n header.event_name == \"AUE_modify_user\",\n \"UserModified\",\n header.event_name == \"AUE_MOUNT\",\n \"VolumeMount\",\n header.event_name == \"AUE_openssh\",\n \"SshInitiated\",\n header.event_name == \"AUE_PIDFORTASK\",\n \"ProcessCreated\",\n header.event_name == \"AUE_POSIX_SPAWN\",\n \"ProcessCreated\",\n header.event_name == \"AUE_remove_from_group\",\n \"UserRemovedFromGroup\",\n header.event_name == \"AUE_SESSION_CLOSE\",\n \"Logoff\",\n header.event_name == \"AUE_SESSION_END\",\n \"Logoff\",\n header.event_name == \"AUE_SESSION_START\",\n \"Logon\",\n header.event_name == \"AUE_SESSION_UPDATE\",\n \"\",\n header.event_name == \"AUE_SETPRIORITY\",\n \"\",\n header.event_name == \"AUE_SETSOCKOPT\",\n \"\",\n header.event_name == \"AUE_SETTIMEOFDAY\",\n \"SystemChange\",\n header.event_name == \"AUE_shutdown\",\n \"ShutdownInitiated\",\n header.event_name == \"AUE_SOCKETPAIR\",\n \"\",\n header.event_name == \"AUE_ssauthint\",\n \"Elevate\",\n header.event_name == \"AUE_ssauthmech\",\n \"Elevate\",\n header.event_name == \"AUE_ssauthorize\",\n \"Elevate\",\n header.event_name == \"AUE_TASKFORPID\",\n \"\",\n header.event_name == \"AUE_TASKNAMEFORPID\",\n \"\",\n header.event_name == \"AUE_UNMOUNT\",\n \"VolumeUnmount\",\n header.event_name == \"AUE_WAIT4\",\n \"ProcessTerminated\",\n header.event_name == \"PLAINTEXT_LOG_COLLECTION_EVENT\",\n \"LogFileCollected\",\n header.event_name == \"SYSTEM_PERFORMANCE_METRICS\",\n \"SystemPerformanceMetrics\",\n \"Unknown\"\n ),\n //\n // Jamf Protect Telemetry - Process\n //\n ActingProcessId = toreal(subject.responsible_process_id),\n ActingProcessName = tostring(subject.responsible_process_name),\n ParentProcessName = tostring(subject.parent_path),\n ParentProcessId = toreal(subject.parent_pid),\n ParentProcessGuid = tostring(subject.parent_uuid),\n TargetProcessName = tostring(subject.process_name),\n TargetProcessId = toreal(subject.process_id),\n TargetProcessGuid = tostring(exec_chain.uuid),\n TargetProcessSHA256 = tostring(subject.process_hash),\n TargetUserId = toreal(subject.user_id),\n TargetUsername = tostring(subject.user_name),\n TargetProcessCommandLine = exec_args.args_compiled,\n ActorUsername = tostring(subject.effective_user_name),\n ActorUserId = toreal(subject.audit_user_name),\n //\n // Jamf Protect Telemetry - Audit/Group\n //\n GroupName = tostring(subject.group_name),\n GroupID = toreal(subject.group_id),\n EffectiveGroupName = tostring(subject.effective_group_name),\n EffectiveGroupID = toreal(subject.effective_group_id),\n //\n // Jamf Protect Telemetry - Network\n //\n DstIpAddr = socket_inet.ip_address,\n DstPortNumber = socket_inet.port,\n NetworkProtocolVersion = case(socket_inet.id == 128, \"IPV4\", socket_inet.id == 129, \"IPV6\", \"\"),\n SrcIpAddr = subject.terminal.id.ip.address,\n //\n // Jamf Protect Telemetry - Binaries\n //\n TargetBinarySHA256 = tostring(identity.cd_hash),\n TargetbinarySignerType = case(identity.signer_type == 0, \"Developer\", identity.signer_type == 1, \"Apple\", \"\"),\n TargetBinarySigningTeamID = tostring(identity.team_id),\n TargetBinarySigningAppID = tostring(identity.signer_id),\n //\n // Jamf Protect Telemetry - Log File Collection\n //\n TargetFilePath = path\n| project-away _event_score\n\n", + "outputStream": "Custom-jamfprotecttelemetryv1_CL" + }, + { + "streams": [ + "Custom-jamfprotectalerts" + ], + "destinations": [ + "clv2ws1" + ], + "transformKql": "source\n//ASIM - Generic Fields\n| extend\n EventVendor = \"Jamf\",\n EventProduct = \"Alerts Stream\",\n // EventSchemaVersion = metadata.schemaVersion,\n EventProductVersion = input.host.protectVersion,\n EventSeverity = case(input.match.severity == 0, \"Informational\", input.match.severity == 1, \"Low\", input.match.severity == 2, \"Medium\", input.match.severity == 3, \"High\", \"Informational\"),\n EventOriginalType = input.eventType,\n EventOriginalUid = input.match.uuid,\n EventType = case(\n input.eventType == \"GPClickEvent\",\n \"Click\",\n input.eventType == \"GPDownloadEvent\",\n \"Download\",\n input.eventType == \"GPFSEvent\",\n \"FileSystem\",\n input.eventType == \"GPProcessEvent\",\n \"Process\",\n input.eventType == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input.eventType == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input.eventType == \"GPMRTEvent\",\n \"MRT\",\n input.eventType == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input.eventType == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input.eventType == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input.eventType == \"GPUSBEvent\",\n \"USB\",\n input.eventType == \"auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventResult = case(input.match.actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventMessage = input.match.facts[0].name,\n EventResultMessage = input.match.facts[0].human,\n //\n // Jamf Protect - Device Hostnames\n //\n TargetHostname = input.host.hostname,\n DvcHostname = input.host.hostname,\n DvcSerial = input.host.serial,\n DvcIpAddr = input.host.ips,\n DvcId = input.host.provisioningUDID,\n DvcOs = \"macOS\",\n DvcOsVersion = input.host.os,\n SrcDeviceType = \"Computer\",\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = case(input.match.event.type == 0, \"None\", input.match.event.type == 1, \"Create\", input.match.event.type == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input.match.event.subType == 7, \"Exec\", input.match.event.subType == 1, \"Fork\", input.match.event.subType == 23, \"Execve\", input.match.event.subType == 43190, \"Posix Spawn\", \"\"),\n ActingProcessName = tostring(input.related.processes[array_length(input.related.processes) - 1].path),\n ActingProcessId = toreal(input.related.processes[0].responsiblePID),\n ActingProcessGuid = tostring(input.related.processes[array_length(input.related.processes) - 1].uuid),\n ParentProcessName = todynamic(iff(array_length(input.related.processes) > 1, tostring(input.related.processes[1].path), \"\")),\n ParentProcessId = iff(array_length(input.related.processes) > 1, toreal(input.related.processes[1].pid), double(null)),\n ParentProcessGuid = tostring(iff(array_length(input.related.processes) > 1, tostring(input.related.processes[1].uuid), \"\")),\n TargetProcessName = todynamic(input.related.processes[0].name),\n TargetProcessId = input.related.processes[0].pid,\n TargetProcessGuid = input.related.processes[0].uuid,\n TargetProcessSHA1 = tostring(input.related.binaries[0].sha1hex),\n TargetProcessSHA256 = tostring(input.related.binaries[0].sha256hex),\n TargetProcessCommandLine = input.related.processes[0].args,\n TargetProcessCurrentDirectory = tostring(input.related.processes[0].path),\n TargetProcessStatusCode = toreal(input.related.processes[0].exitCode),\n //\n // Jamf Protect Alerts - Files\n //\n TargetFilePath = input.related.files[0].path,\n TargetFileSHA1 = input.related.files[0].sha1hex,\n TargetFileSHA256 = input.related.files[0].sha256hex,\n TargetFileSize = input.related.files[0].size,\n TargetFileSigningInfoMessage = input.related.files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(input.related.files[0].signingInfo.signerType == 0, \"Apple\", input.related.files[0].signingInfo.signerType == 1, \"App Store\", input.related.files[0].signingInfo.signerType == 2, \"Developer\", input.related.files[0].signingInfo.signerType == 3, \"Ad Hoc\", input.related.files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = input.related.files[0].signingInfo.teamid,\n TargetFileIsDownload = tobool(input.related.files[0].isDownload),\n TargetFileIsAppBundle = tobool(input.related.files[0].isAppBundle),\n TargetFileIsDirectory = tobool(input.related.files[0].isDirectory),\n TargetFileIsScreenshot = tobool(input.related.files[0].isScreenShot),\n TargetFileExtendedAttributes = input.related.files[0].xattrs,\n // Jamf Protect Alerts - Binaries\n TargetBinaryFilePath = input.related.binaries[0].path,\n TargetBinarySHA1 = input.related.binaries[0].sha1hex,\n TargetBinarySHA256 = input.related.binaries[0].sha256hex,\n TargetBinarySigningInfoMessage = input.related.binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(input.related.binaries[0].signingInfo.signerType == 0, \"Apple\", input.related.binaries[0].signingInfo.signerType == 1, \"App Store\", input.related.binaries[0].signingInfo.signerType == 2, \"Developer\", input.related.binaries[0].signingInfo.signerType == 3, \"Ad Hoc\", input.related.binaries[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetBinarySigningTeamID = input.related.binaries[0].signingInfo.teamid,\n TargetBinarySigningAppID = input.related.binaries[0].signingInfo.appid\n| project-away\n caid,\n certid\n", + "outputStream": "Custom-jamfprotectalerts_CL" + } + ], + "dataCollectionEndpointId": "[concat('/subscriptions/',parameters('subscription'),'/resourceGroups/',parameters('resourceGroupName'),'/providers/Microsoft.Insights/dataCollectionEndpoints/',parameters('workspace'))]" + } + }, + { + "name": "jamfprotecttelemetryv2_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "plan": "Analytics", + "schema": { + "name": "jamfprotecttelemetryv2_CL", + "columns": [ + { + "name": "action", + "type": "dynamic" + }, + { + "name": "event", + "type": "dynamic" + }, + { + "name": "EventOriginalType", + "type": "int" + }, + { + "name": "EventCount", + "type": "int" + }, + { + "name": "process", + "type": "dynamic" + }, + { + "name": "thread", + "type": "dynamic" + }, + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "EventOriginalUid", + "type": "string" + }, + { + "name": "EventVendor", + "type": "dynamic" + }, + { + "name": "EventProduct", + "type": "dynamic" + }, + { + "name": "EventSchemaVersion", + "type": "dynamic" + }, + { + "name": "EventProductVersion", + "type": "dynamic" + }, + { + "name": "EventSeverity", + "type": "string" + }, + { + "name": "TargetHostname", + "type": "dynamic" + }, + { + "name": "DvcHostname", + "type": "dynamic" + }, + { + "name": "DvcSerial", + "type": "dynamic" + }, + { + "name": "DvcIpAddr", + "type": "dynamic" + }, + { + "name": "DvcId", + "type": "dynamic" + }, + { + "name": "DvcOs", + "type": "string" + }, + { + "name": "DvcOsVersion", + "type": "dynamic" + }, + { + "name": "SrcDeviceType", + "type": "string" + } + ] + }, + "totalRetentionInDays": 30 + } + }, + { + "name": "jamfprotectalerts_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "plan": "Analytics", + "schema": { + "name": "jamfprotectalerts_CL", + "columns": [ + { + "name": "input", + "type": "dynamic" + }, + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "EventVendor", + "type": "string" + }, + { + "name": "EventProduct", + "type": "string" + }, + { + "name": "EventProductVersion", + "type": "dynamic" + }, + { + "name": "EventSeverity", + "type": "string" + }, + { + "name": "EventOriginalType", + "type": "dynamic" + }, + { + "name": "EventOriginalUid", + "type": "dynamic" + }, + { + "name": "EventType", + "type": "string" + }, + { + "name": "EventResult", + "type": "string" + }, + { + "name": "EventMessage", + "type": "dynamic" + }, + { + "name": "EventResultMessage", + "type": "dynamic" + }, + { + "name": "TargetHostname", + "type": "dynamic" + }, + { + "name": "DvcHostname", + "type": "dynamic" + }, + { + "name": "DvcSerial", + "type": "dynamic" + }, + { + "name": "DvcIpAddr", + "type": "dynamic" + }, + { + "name": "DvcId", + "type": "dynamic" + }, + { + "name": "DvcOs", + "type": "string" + }, + { + "name": "DvcOsVersion", + "type": "dynamic" + }, + { + "name": "SrcDeviceType", + "type": "string" + }, + { + "name": "ProcessEventType", + "type": "string" + }, + { + "name": "ProcessEventSubType", + "type": "string" + }, + { + "name": "ActingProcessName", + "type": "string" + }, + { + "name": "ActingProcessId", + "type": "real" + }, + { + "name": "ActingProcessGuid", + "type": "string" + }, + { + "name": "ParentProcessName", + "type": "dynamic" + }, + { + "name": "ParentProcessId", + "type": "real" + }, + { + "name": "ParentProcessGuid", + "type": "string" + }, + { + "name": "TargetProcessName", + "type": "dynamic" + }, + { + "name": "TargetProcessId", + "type": "dynamic" + }, + { + "name": "TargetProcessGuid", + "type": "dynamic" + }, + { + "name": "TargetProcessSHA1", + "type": "string" + }, + { + "name": "TargetProcessSHA256", + "type": "string" + }, + { + "name": "TargetProcessCommandLine", + "type": "dynamic" + }, + { + "name": "TargetProcessCurrentDirectory", + "type": "string" + }, + { + "name": "TargetProcessStatusCode", + "type": "real" + }, + { + "name": "TargetFilePath", + "type": "dynamic" + }, + { + "name": "TargetFileSHA1", + "type": "dynamic" + }, + { + "name": "TargetFileSHA256", + "type": "dynamic" + }, + { + "name": "TargetFileSize", + "type": "dynamic" + }, + { + "name": "TargetFileSigningInfoMessage", + "type": "dynamic" + }, + { + "name": "TargetFileSignerType", + "type": "string" + }, + { + "name": "TargetFileSigningTeamID", + "type": "dynamic" + }, + { + "name": "TargetFileIsDownload", + "type": "boolean" + }, + { + "name": "TargetFileIsAppBundle", + "type": "boolean" + }, + { + "name": "TargetFileIsDirectory", + "type": "boolean" + }, + { + "name": "TargetFileIsScreenshot", + "type": "boolean" + }, + { + "name": "TargetFileExtendedAttributes", + "type": "dynamic" + }, + { + "name": "TargetBinaryFilePath", + "type": "dynamic" + }, + { + "name": "TargetBinarySHA1", + "type": "dynamic" + }, + { + "name": "TargetBinarySHA256", + "type": "dynamic" + }, + { + "name": "TargetBinarySigningInfoMessage", + "type": "dynamic" + }, + { + "name": "TargetbinarySignerType", + "type": "string" + }, + { + "name": "TargetBinarySigningTeamID", + "type": "dynamic" + }, + { + "name": "TargetBinarySigningAppID", + "type": "dynamic" + } + ] + }, + "totalRetentionInDays": 30 + } + }, + { + "name": "jamfprotecttelemetryv1_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "plan": "Analytics", + "schema": { + "name": "jamfprotecttelemetryv1_CL", + "columns": [ + { + "name": "architecture", + "type": "string" + }, + { + "name": "arguments", + "type": "dynamic" + }, + { + "name": "attributes", + "type": "dynamic" + }, + { + "name": "bios_firmware_versions", + "type": "dynamic" + }, + { + "name": "contents", + "type": "string" + }, + { + "name": "exec_args", + "type": "dynamic" + }, + { + "name": "exec_chain", + "type": "dynamic" + }, + { + "name": "exec_chain_child", + "type": "dynamic" + }, + { + "name": "exec_chain_parent", + "type": "dynamic" + }, + { + "name": "exec_env", + "type": "dynamic" + }, + { + "name": "exit", + "type": "dynamic" + }, + { + "name": "file", + "type": "dynamic" + }, + { + "name": "header", + "type": "dynamic" + }, + { + "name": "host_info", + "type": "dynamic" + }, + { + "name": "identity", + "type": "dynamic" + }, + { + "name": "key", + "type": "string" + }, + { + "name": "metrics", + "type": "dynamic" + }, + { + "name": "page_info", + "type": "dynamic" + }, + { + "name": "path", + "type": "dynamic" + }, + { + "name": "process", + "type": "dynamic" + }, + { + "name": "rateLimitingSeconds", + "type": "int" + }, + { + "name": "return", + "type": "dynamic" + }, + { + "name": "socket_inet", + "type": "dynamic" + }, + { + "name": "subject", + "type": "dynamic" + }, + { + "name": "texts", + "type": "string" + }, + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "EventVendor", + "type": "string" + }, + { + "name": "EventProduct", + "type": "string" + }, + { + "name": "EventSeverity", + "type": "string" + }, + { + "name": "TargetModel", + "type": "dynamic" + }, + { + "name": "DvcOsVersion", + "type": "dynamic" + }, + { + "name": "TargetHostname", + "type": "dynamic" + }, + { + "name": "DvcHostname", + "type": "dynamic" + }, + { + "name": "DvcId", + "type": "dynamic" + }, + { + "name": "EventType", + "type": "string" + }, + { + "name": "ActingProcessId", + "type": "dynamic" + }, + { + "name": "ActingProcessName", + "type": "dynamic" + }, + { + "name": "ParentProcessName", + "type": "dynamic" + }, + { + "name": "ParentProcessId", + "type": "dynamic" + }, + { + "name": "ParentProcessGuid", + "type": "dynamic" + }, + { + "name": "TargetProcessName", + "type": "dynamic" + }, + { + "name": "TargetProcessId", + "type": "dynamic" + }, + { + "name": "TargetProcessGuid", + "type": "dynamic" + }, + { + "name": "TargetProcessSHA256", + "type": "dynamic" + }, + { + "name": "TargetUserId", + "type": "dynamic" + }, + { + "name": "TargetUsername", + "type": "dynamic" + }, + { + "name": "TargetProcessCommandLine", + "type": "dynamic" + }, + { + "name": "ActorUsername", + "type": "dynamic" + }, + { + "name": "ActorUserId", + "type": "dynamic" + }, + { + "name": "GroupName", + "type": "dynamic" + }, + { + "name": "GroupID", + "type": "dynamic" + }, + { + "name": "EffectiveGroupName", + "type": "dynamic" + }, + { + "name": "EffectiveGroupID", + "type": "dynamic" + }, + { + "name": "DstIpAddr", + "type": "dynamic" + }, + { + "name": "DstPortNumber", + "type": "dynamic" + }, + { + "name": "NetworkProtocolVersion", + "type": "string" + }, + { + "name": "SrcIpAddr", + "type": "dynamic" + }, + { + "name": "TargetBinarySHA256", + "type": "dynamic" + }, + { + "name": "TargetbinarySignerType", + "type": "string" + }, + { + "name": "TargetBinarySigningTeamID", + "type": "string" + }, + { + "name": "TargetBinarySigningAppID", + "type": "string" + }, + { + "name": "TargetFilePath", + "type": "dynamic" + } + ] + }, + "totalRetentionInDays": 30 + } + }, + { + "name": "jamfprotectunifiedlogs_CL", + "apiVersion": "2022-10-01", + "type": "Microsoft.OperationalInsights/workspaces/tables", + "location": "[parameters('workspace-location')]", + "kind": null, + "properties": { + "plan": "Analytics", + "schema": { + "name": "jamfprotectunifiedlogs_CL", + "columns": [ + { + "name": "input", + "type": "dynamic" + }, + { + "name": "TimeGenerated", + "type": "datetime" + }, + { + "name": "EventProductVersion", + "type": "dynamic" + }, + { + "name": "EventSeverity", + "type": "string" + }, + { + "name": "EventOriginalType", + "type": "dynamic" + }, + { + "name": "EventOriginalUid", + "type": "dynamic" + }, + { + "name": "EventType", + "type": "string" + }, + { + "name": "EventResult", + "type": "string" + }, + { + "name": "EventMessage", + "type": "dynamic" + }, + { + "name": "EventResultMessage", + "type": "dynamic" + }, + { + "name": "TargetHostname", + "type": "dynamic" + }, + { + "name": "DvcHostname", + "type": "dynamic" + }, + { + "name": "DvcSerial", + "type": "dynamic" + }, + { + "name": "DvcIpAddr", + "type": "dynamic" + }, + { + "name": "DvcId", + "type": "dynamic" + }, + { + "name": "DvcOs", + "type": "string" + }, + { + "name": "DvcOsVersion", + "type": "dynamic" + }, + { + "name": "SrcDeviceType", + "type": "string" + }, + { + "name": "ProcessEventType", + "type": "string" + }, + { + "name": "ProcessEventSubType", + "type": "string" + }, + { + "name": "TargetProcessName", + "type": "dynamic" + }, + { + "name": "TargetProcessId", + "type": "dynamic" + }, + { + "name": "TargetProcessGuid", + "type": "dynamic" + }, + { + "name": "TargetProcessCommandLine", + "type": "dynamic" + }, + { + "name": "TargetProcessCurrentDirectory", + "type": "dynamic" + } + ] + }, + "totalRetentionInDays": 30 } } ] @@ -298,95 +1701,87 @@ "packageKind": "Solution", "packageVersion": "[variables('_solutionVersion')]", "packageName": "[variables('_solutionName')]", + "contentProductId": "[concat(take(variables('_solutionId'), 50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentIdConnectorDefinition2'),'-', variables('dataConnectorCCPVersion'))))]", "packageId": "[variables('_solutionId')]", "contentSchemaVersion": "3.0.0", - "contentId": "[variables('_dataConnectorContentId1')]", - "contentKind": "DataConnector", - "displayName": "Jamf Protect", - "contentProductId": "[variables('_dataConnectorcontentProductId1')]", - "id": "[variables('_dataConnectorcontentProductId1')]", - "version": "[variables('dataConnectorVersion1')]" - } - }, - { - "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", - "apiVersion": "2023-04-01-preview", - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", - "dependsOn": [ - "[variables('_dataConnectorId1')]" - ], - "location": "[parameters('workspace-location')]", - "properties": { - "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", - "contentId": "[variables('_dataConnectorContentId1')]", - "kind": "DataConnector", - "version": "[variables('dataConnectorVersion1')]", - "source": { - "kind": "Solution", - "name": "Jamf Protect", - "sourceId": "[variables('_solutionId')]" - }, - "author": { - "name": "Thijs Xhaflaire", - "email": "[variables('_email')]" - }, - "support": { - "name": "Jamf Software, LLC", - "email": "support@jamf.com", - "tier": "Partner", - "link": "https://www.jamf.com/support/" - } + "version": "[variables('dataConnectorCCPVersion')]" } }, { - "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", - "apiVersion": "2021-03-01-preview", - "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentIdConnectorDefinition2'))]", + "apiVersion": "2022-09-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectorDefinitions", "location": "[parameters('workspace-location')]", - "kind": "GenericUI", + "kind": "Customizable", "properties": { "connectorUiConfig": { - "title": "Jamf Protect", + "id": "JamfProtectPush", + "title": "Jamf Protect Push Connector", "publisher": "Jamf", "descriptionMarkdown": "The [Jamf Protect](https://www.jamf.com/products/jamf-protect/) connector provides the capability to read raw event data from Jamf Protect in Microsoft Sentinel.", "graphQueries": [ { - "metricName": "Total Activities data received", - "legend": "jamfprotect_CL", - "baseQuery": "jamfprotect_CL" - } - ], - "dataTypes": [ + "metricName": "Telemetry", + "legend": "jamfprotecttelemetryv2_CL", + "baseQuery": "jamfprotecttelemetryv2_CL" + }, { - "name": "jamfprotect_CL", - "lastDataReceivedQuery": "jamfprotect_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + "metricName": "Unified Logs", + "legend": "jamfprotectunifiedlogs_CL", + "baseQuery": "jamfprotectunifiedlogs_CL" + }, + { + "metricName": "Telemetry (Legacy)", + "legend": "jamfprotecttelemetryv1_CL", + "baseQuery": "jamfprotecttelemetryv1_CL" + }, + { + "metricName": "Alerts", + "legend": "jamfprotectalerts_CL", + "baseQuery": "jamfprotectalerts_CL" } ], - "connectivityCriterias": [ + "sampleQueries": [ { - "type": "IsConnectedQuery", - "value": [ - "jamfprotect_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)" - ] + "description": "Jamf Protect - All Alerts", + "query": "jamfprotectalerts_CL\n | sort by TimeGenerated desc" + }, + { + "description": "Jamf Protect - All Telemetry events", + "query": "jamfprotecttelemetry_CL\n | sort by TimeGenerated desc" } ], - "sampleQueries": [ + "dataTypes": [ { - "description": "Jamf Protect - All events.", - "query": "jamfprotect_CL\n | sort by TimeGenerated desc" + "name": "jamfprotecttelemetryv2_CL", + "lastDataReceivedQuery": "jamfprotecttelemetryv2_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" }, { - "description": "Jamf Protect - All active endpoints.", - "query": "jamfprotect_CL\n | where notempty(input_host_hostname_s) | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | sort by Event desc" + "name": "jamfprotectunifiedlogs_CL", + "lastDataReceivedQuery": "jamfprotectunifiedlogs_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" }, { - "description": "Jamf Protect - Top 10 endpoints with Alerts", - "query": "jamfprotect_CL\n | where topicType_s == 'alert' and notempty(input_eventType_s) and notempty(input_host_hostname_s)\n | summarize Event = count() by input_host_hostname_s\n | project-rename HostName = input_host_hostname_s\n | top 10 by Event" + "name": "jamfprotecttelemetryv1_CL", + "lastDataReceivedQuery": "jamfprotecttelemetryv1_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + }, + { + "name": "jamfprotectalerts_CL", + "lastDataReceivedQuery": "jamfprotectalerts_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriteria": [ + { + "type": "IsConnectedQuery", + "value": [ + "jamfprotecttelemetryv2_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)", + "jamfprotectunifiedlogs_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)", + "jamfprotecttelemetryv1_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)", + "jamfprotectalerts_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(7d)" + ] } ], "availability": { - "status": 1, - "isPreview": false + "status": 1 }, "permissions": { "resourceProvider": [ @@ -400,27 +1795,268 @@ "read": true, "delete": true } + } + ], + "customs": [ + { + "name": "Microsoft Entra", + "description": "Permission to create an app registration in Microsoft Entra ID. Typically requires Entra ID Application Developer role or higher." }, { - "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", - "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", - "providerDisplayName": "Keys", - "scope": "Workspace", - "requiredPermissions": { - "action": true - } + "name": "Microsoft Azure", + "description": "Permission to assign Monitoring Metrics Publisher role on data collection rule (DCR). Typically requires Azure RBAC Owner or User Access Administrator role" } ] }, "instructionSteps": [ { - "description": "This connector reads data from the jamfprotect_CL table created by Jamf Protect in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API." + "title": "1. Create ARM Resources and Provide the Required Permissions", + "description": "This connector reads data from the tables that Jamf Protect uses in a Microsoft Analytics Workspace, if the [data forwarding](https://docs.jamf.com/jamf-protect/documentation/Data_Forwarding_to_a_Third_Party_Storage_Solution.html?hl=sentinel#task-4227) option is enabled in Jamf Protect then raw event data is sent to the Microsoft Sentinel Ingestion API.", + "instructions": [ + { + "type": "Markdown", + "parameters": { + "content": "#### Automated Configuration and Secure Data Ingestion with Entra Application \nClicking on \"Connect\" will trigger the creation of Log Analytics tables and a Data Collection Rule (DCR). \nIt will then create an Entra application, link the DCR to it, and set the entered secret in the application. This setup enables data to be sent securely to the DCR using an Entra token." + } + }, + { + "parameters": { + "label": "Deploy Jamf Protect connector resources", + "applicationDisplayName": "Jamf Protect Connector Application" + }, + "type": "DeployPushConnectorButton" + } + ] + }, + { + "title": "2. Push your logs into the workspace", + "description": "Use the following parameters to configure the your machine to send the logs to the workspace.", + "instructions": [ + { + "parameters": { + "label": "Tenant ID (Directory ID)", + "fillWith": [ + "TenantId" + ] + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Entra Application ID", + "fillWith": [ + "ApplicationId" + ], + "placeholder": "Deploy push connector to get the Application ID" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Entra Application Secret", + "fillWith": [ + "ApplicationSecret" + ], + "placeholder": "Deploy push connector to get the Application Secret" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "DCE Uri", + "fillWith": [ + "DataCollectionEndpoint" + ], + "placeholder": "Deploy push connector to get the DCR Uri" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "DCR Immutable ID", + "fillWith": [ + "DataCollectionRuleId" + ], + "placeholder": "Deploy push connector to get the DCR ID" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Telemetry Stream ID", + "value": "Custom-jamfprotecttelemetryv1_CL" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Unified Logs Stream ID", + "value": "Custom-jamfprotectunifiedlogs_CL" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Telemetry (Legacy) Stream ID", + "value": "Custom-jamfprotecttelemetryv2_CL" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "label": "Alerts Stream ID", + "value": "Custom-jamfprotectalerts_CL" + }, + "type": "CopyableLabel" + } + ] } - ], - "id": "[variables('_uiConfigId1')]" + ] + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnectorDefinition2')))]", + "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectorDefinitions', variables('_dataConnectorContentIdConnectorDefinition2'))]", + "contentId": "[variables('_dataConnectorContentIdConnectorDefinition2')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorCCPVersion')]", + "source": { + "sourceId": "[variables('_solutionId')]", + "name": "[variables('_solutionName')]", + "kind": "Solution" + }, + "author": { + "name": "Thijs Xhaflaire", + "email": "[variables('_email')]" + }, + "support": { + "name": "Jamf Software, LLC", + "email": "support@jamf.com", + "tier": "Partner", + "link": "https://www.jamf.com/support/" + }, + "dependencies": { + "criteria": [ + { + "version": "[variables('dataConnectorCCPVersion')]", + "contentId": "[variables('_dataConnectorContentIdConnections2')]", + "kind": "ResourcesDataConnector" + } + ] } } }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('dataConnectorTemplateNameConnections2'), variables('dataConnectorCCPVersion'))]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "contentId": "[variables('_dataConnectorContentIdConnections2')]", + "displayName": "Jamf Protect Push Connector", + "contentKind": "ResourcesDataConnector", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorCCPVersion')]", + "parameters": { + "auth": { + "type": "object", + "defaultValue": { + "appId": "[[parameters('auth').appId]]", + "servicePrincipalId": "[[parameters('auth').servicePrincipalId]]" + } + }, + "connectorDefinitionName": { + "defaultValue": "Jamf Protect Push Connector", + "type": "string", + "minLength": 1 + }, + "workspace": { + "defaultValue": "[parameters('workspace')]", + "type": "string" + }, + "dcrConfig": { + "defaultValue": { + "dataCollectionEndpoint": "data collection Endpoint", + "dataCollectionRuleImmutableId": "data collection rule immutableId" + }, + "type": "object" + } + }, + "variables": { + "_dataConnectorContentIdConnections2": "[variables('_dataConnectorContentIdConnections2')]" + }, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', variables('_dataConnectorContentIdConnections2')))]", + "apiVersion": "2022-01-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentIdConnections2'))]", + "contentId": "[variables('_dataConnectorContentIdConnections2')]", + "kind": "ResourcesDataConnector", + "version": "[variables('dataConnectorCCPVersion')]", + "source": { + "sourceId": "[variables('_solutionId')]", + "name": "[variables('_solutionName')]", + "kind": "Solution" + }, + "author": { + "name": "Thijs Xhaflaire", + "email": "[variables('_email')]" + }, + "support": { + "name": "Jamf Software, LLC", + "email": "support@jamf.com", + "tier": "Partner", + "link": "https://www.jamf.com/support/" + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', 'JamfProtectPushConnectorPolling')]", + "apiVersion": "2023-02-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "Push", + "properties": { + "connectorDefinitionName": "JamfProtectPush", + "dcrConfig": { + "streamName": "Custom-jamfprotecttelemetryv2", + "dataCollectionEndpoint": "[[parameters('dcrConfig').dataCollectionEndpoint]", + "dataCollectionRuleImmutableId": "[[parameters('dcrConfig').dataCollectionRuleImmutableId]" + }, + "auth": { + "type": "Push", + "AppId": "[[parameters('auth').appId]", + "ServicePrincipalId": "[[parameters('auth').servicePrincipalId]" + }, + "request": {}, + "response": { + "eventsJsonPaths": [ + "$.messages" + ] + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "contentProductId": "[concat(take(variables('_solutionId'), 50),'-','rdc','-', uniqueString(concat(variables('_solutionId'),'-','ResourcesDataConnector','-',variables('_dataConnectorContentIdConnections2'),'-', variables('dataConnectorCCPVersion'))))]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "version": "[variables('dataConnectorCCPVersion')]" + } + }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", "apiVersion": "2023-04-01-preview", @@ -447,7 +2083,7 @@ "displayName": "JamfProtect", "category": "Microsoft Sentinel Parser", "functionAlias": "JamfProtect", - "query": "let JamfProtectAlerts_view = view () {\n jamfprotect_CL\n| where topicType_s == \"alert\"\n and input_eventType_s <> \"GPUnifiedLogEvent\"\n and isnotempty(input_match_severity_d)\n// JSON Parsing at earliest stage\n| extend \n Related_users = parse_json(input_related_users_s),\n Related_files = parse_json(input_related_files_s),\n Related_binaries = parse_json(input_related_binaries_s),\n Related_groups = parse_json(input_related_groups_s),\n Related_processes = parse_json(input_related_processes_s),\n Match_facts = parse_json(input_match_facts_s),\n Match_tags = parse_json(input_match_tags_s),\n Match_actions = parse_json(input_match_actions_s),\n Match_context = parse_json(input_match_context_s),\n Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)\n// ASIM - Common Fields\n| extend EventVendor = 'Jamf'\n| extend EventProduct = 'Jamf Protect - Alerts'\n| project-rename\n EventOriginalUid = input_match_uuid_g\n| extend\n // Jamf Protect - Common Fields\n EventType = case(\n input_eventType_s == \"GPClickEvent\",\n \"Click\",\n input_eventType_s == \"GPDownloadEvent\",\n \"Download\",\n input_eventType_s == \"GPFSEvent\",\n \"FileSystem\",\n input_eventType_s == \"GPProcessEvent\",\n \"Process\",\n input_eventType_s == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input_eventType_s == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input_eventType_s == \"GPMRTEvent\",\n \"MRT\",\n input_eventType_s == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input_eventType_s == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input_eventType_s == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input_eventType_s == \"GPUSBEvent\",\n \"USB\",\n input_eventType_s == \"auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),\n EventMessage = coalesce(Match_facts[1].name, Match_facts[0].name),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = case(Match_actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventProductVersion = column_ifexists(\"input_host_protectVersion_s\", \"\"),\n //\n // Jamf Protect - Alert details\n //\n EventSeverity = case(input_match_severity_d == 0, \"Informational\", input_match_severity_d == 1, \"Low\", input_match_severity_d == 2, \"Medium\", input_match_severity_d == 3, \"High\", \"Informational\"),\n EventMatch = column_ifexists(\"input_match_event_matchValue_s\", \"\"),\n EventMatchType = column_ifexists(\"input_match_event_matchType_s\", \"\"),\n EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", EventOriginalUid),\n //\n // Jamf Protect - Source User\n SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect - Source Device Hostnames\n //\n TargetHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"input_host_provisioningUDID_g\", \"\"),\n DvcOs=\"macOS\",\n SrcDeviceType=\"Computer\",\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = case(input_match_event_type_d == 0, \"None\", input_match_event_type_d == 1, \"Create\", input_match_event_type_d == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input_match_event_subType_d == 7, \"Exec\", input_match_event_subType_d == 1, \"Fork\", input_match_event_subType_d == 23, \"Execve\", input_match_event_subType_d == 43190, \"Posix Spawn\", \"\"),\n ActingProcessName = tostring(Related_processes[array_length(Related_processes) - 1].path),\n ActingProcessCreationTime = format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[array_length(Related_processes) - 1].startTimestamp)), 'HH:mm:ss'),\n ActingProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].responsiblePID)),\n ActingProcessGuid = tostring(Related_processes[array_length(Related_processes) - 1].uuid),\n ParentProcessName = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].path), \"\"),\n ParentProcessCreationTime = iff(array_length(Related_processes) > 1, format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[1].startTimestamp)), 'HH:mm:ss'), \"\"),\n ParentProcessId = iff(array_length(Related_processes) > 1, toreal(Related_processes[1].pid), double(null)),\n ParentProcessGuid = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].uuid), \"\"),\n TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),\n TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),\n TargetProcessGuid = tostring(Related_processes[0].uuid),\n TargetProcessSHA1 = Related_binaries[0].sha1hex,\n TargetProcessSHA256 = Related_binaries[0].sha256hex,\n TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),\n TargetProcessCommandLine = column_ifexists(\"input_match_event_process_args_s\", \"\"),\n TargetProcessCurrentDirectory = column_ifexists(\"input_match_event_process_path_s\", \"\"),\n //TargetProcessStatusCode = column_ifexists(Related_processes[0].exitCode, \"\"),\n TargetUserId = toreal(coalesce(Related_users[1].uid, Related_processes[0].uid)),\n TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].uid)),\n //\n // Jamf Protect Alerts - Files\n //\n TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),\n TargetFileSHA1 = Related_files[0].sha1hex,\n TargetFileSHA256 = Related_files[0].sha256hex,\n TargetFileSize = Related_files[0].size,\n TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, \"Apple\", Related_files[0].signingInfo.signerType == 1, \"App Store\", Related_files[0].signingInfo.signerType == 2, \"Developer\", Related_files[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,\n TargetFileIsDownload = case(Related_files[0].isDownload == \"true\", \"true\", Related_files[0].isDownload == \"false\", \"false\", \"\"),\n TargetFileIsAppBundle = case(Related_files[0].isAppBundle == \"true\", \"true\", Related_files[0].isAppBundle == \"false\", \"false\", \"\"),\n TargetFileIsDirectory = case(Related_files[0].isDirectory == \"true\", \"true\", Related_files[0].isDirectory == \"false\", \"false\", \"\"),\n TargetFileIsScreenshot = case(Related_files[0].isScreenShot == \"true\", \"true\", Related_files[0].isScreenShot == \"false\", \"false\", \"\"),\n //\n // Jamf Protect Alerts - Binaries\n TargetBinaryFilePath = Related_binaries[0].path,\n TargetBinarySHA1 = tostring(Related_binaries[0].sha1hex),\n TargetBinarySHA256 = tostring(Related_binaries[0].sha256hex),\n TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(Related_binaries[0].signingInfo.signerType == 0, \"Apple\", Related_binaries[0].signingInfo.signerType == 1, \"App Store\", Related_binaries[0].signingInfo.signerType == 2, \"Developer\", Related_binaries[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_binaries[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetBinarySigningTeamID = tostring(Related_binaries[0].signingInfo.teamid),\n TargetBinarySigningAppID = tostring(Related_binaries[0].signingInfo.appid)\n| project-reorder\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventMessage,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventProductVersion,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ActingProcessName,\n ActingProcessCreationTime,\n ActingProcessId,\n ActingProcessGuid,\n ParentProcessName,\n ParentProcessCreationTime,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessSHA256,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n //TargetProcessStatusCode,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n TargetBinaryFilePath,\n TargetBinarySHA1,\n TargetBinarySHA256,\n TargetBinarySigningInfoMessage,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event_*\n| project-keep\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventMessage,\n EventProductVersion,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ActingProcessName,\n ActingProcessCreationTime,\n ActingProcessId,\n ActingProcessGuid,\n ParentProcessName,\n ParentProcessCreationTime,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessSHA256,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n //TargetProcessStatusCode,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n TargetBinaryFilePath,\n TargetBinarySHA1,\n TargetBinarySHA256,\n TargetBinarySigningInfoMessage,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event_*\n};\n//\n// Jamf Protect - Unified Logs\n//\nlet JamfProtectUnifiedLog_view = view () {\n jamfprotect_CL\n | where input_eventType_s == \"GPUnifiedLogEvent\"\n and isnotempty(input_match_severity_d)\n // JSON Parsing at earliest stage\n | extend \n Related_users = parse_json(input_related_users_s),\n Related_files = parse_json(input_related_files_s),\n Related_binaries = parse_json(input_related_binaries_s),\n Related_groups = parse_json(input_related_groups_s),\n Related_processes = parse_json(input_related_processes_s),\n Match_facts = parse_json(input_match_facts_s),\n Match_tags = parse_json(input_match_tags_s),\n Match_actions = parse_json(input_match_actions_s),\n Match_context = parse_json(input_match_context_s),\n Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Unified Log'\n | project-rename\n EventOriginalUid = input_match_uuid_g\n | extend\n // Jamf Protect - Common Fields\n EventType = case(\n input_eventType_s == \"GPClickEvent\",\n \"Click\",\n input_eventType_s == \"GPDownloadEvent\",\n \"Download\",\n input_eventType_s == \"GPFSEvent\",\n \"FileSystem\",\n input_eventType_s == \"GPProcessEvent\",\n \"Process\",\n input_eventType_s == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input_eventType_s == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input_eventType_s == \"GPMRTEvent\",\n \"MRT\",\n input_eventType_s == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input_eventType_s == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input_eventType_s == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input_eventType_s == \"GPUSBEvent\",\n \"USB\",\n input_eventType_s == \"Auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = case(Match_actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n //\n // Jamf Protect - Unified Logs details\n //\n EventSeverity = case(input_match_severity_d == 0, \"Informational\", input_match_severity_d == 1, \"Low\", input_match_severity_d == 2, \"Medium\", input_match_severity_d == 3, \"High\", \"Informational\"),\n EventMatch = column_ifexists(\"input_match_event_matchValue_s\", \"\"),\n EventMatchType = column_ifexists(\"input_match_event_matchType_s\", \"\"),\n EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", EventOriginalUid),\n //\n // Jamf Protect - Source User\n SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect - Source Device Hostnames\n //\n TargetHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"input_host_provisioningUDID_g\", \"\"),\n DvcOs=\"macOS\",\n SrcDeviceType=\"Computer\",\n //\n // Jamf Protect Unified Logs - Process\n //\n //ParentProcessName = coalesce(input_match_event_process_ppid_d, parse_json('input_related_processes_s')[0].ppid), //column_ifexists(\"exec_chain_child_parent_path_s\", \"\"), coalesce('input.match.event.process.ppid', mvindex('input.related.processes{}.ppid', 0))\n ProcessEventType = case(input_match_event_type_d == 0, \"None\", input_match_event_type_d == 1, \"Create\", input_match_event_type_d == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input_match_event_subType_d == 7, \"Exec\", input_match_event_subType_d == 1, \"Fork\", input_match_event_subType_d == 23, \"Execve\", input_match_event_subType_d == 43190, \"Posix Spawn\", \"\"),\n ParentProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].ppid)),\n ParentProcessGuid = tostring(coalesce(input_match_event_process_pgid_d, toreal(Related_processes[0].pgid))),\n TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),\n TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),\n TargetProcessGuid = tostring(Related_processes[0].uuid),\n TargetProcessSHA1 = Related_binaries[0].sha1hex,\n TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),\n TargetProcessCommandLine = column_ifexists(\"input_match_event_process_args_s\", \"\"),\n TargetProcessCurrentDirectory = column_ifexists(\"input_match_event_process_path_s\", \"\"),\n TargetUserId = toreal(coalesce(Related_users[1].uid, Related_users[0].uid)),\n TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect Unified Logs - Files\n //\n TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),\n TargetFileSHA1 = Related_files[0].sha1hex,\n TargetFileSHA256 = Related_files[0].sha256hex,\n TargetFileSize = Related_files[0].size,\n TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, \"Apple\", Related_files[0].signingInfo.signerType == 1, \"App Store\", Related_files[0].signingInfo.signerType == 2, \"Developer\", Related_files[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,\n TargetFileIsDownload = case(Related_files[0].isDownload == \"true\", \"true\", Related_files[0].isDownload == \"false\", \"false\", \"\"),\n TargetFileIsAppBundle = case(Related_files[0].isAppBundle == \"true\", \"true\", Related_files[0].isAppBundle == \"false\", \"false\", \"\"),\n TargetFileIsDirectory = case(Related_files[0].isDirectory == \"true\", \"true\", Related_files[0].isDirectory == \"false\", \"false\", \"\"),\n TargetFileIsScreenshot = case(Related_files[0].isScreenShot == \"true\", \"true\", Related_files[0].isScreenShot == \"false\", \"false\", \"\")\n | project-reorder\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags\n | project-keep\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event*\n};\n//\n// Jamf Protect - Network Traffic\n//\nlet JamfProtectNetworkTraffic_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Network Traffic Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Network Traffic Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventType = \"query\",\n EventSubType = \"request\",\n EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),\n EventResult = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Prevented\", ''),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername = column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs = case(event_device_osType_s == \"MAC_OS\", \"macOS\", event_device_osType_s == \"IOS\", \"iOS\", event_device_osType_s == \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType = case(event_device_osType_s == \"MAC_OS\", \"Computer\", event_device_osType_s == \"IOS\", \"Mobile Device\", event_device_osType_s == \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery = column_ifexists('event_hostName_s', ''),\n DvcAction = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName = column_ifexists('event_domain_s', ''),\n DstIpAddr = column_ifexists('event_destination_ips_s', ''),\n ThreatCategory = column_ifexists('event_eventType_description_s', ''),\n DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),\n DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),\n ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventType,\n EventSubType,\n EventStartTime,\n EventResult,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n DvcOs,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n DnsQueryTypeName,\n DvcAction,\n DnsResponseName,\n ThreatOriginalRiskLevel\n};\n//\n// Jamf Protect - Endpoint Telemetry\n//\nlet JamfProtectTelemetry_view = view () {\n jamfprotect_CL\n | where header_event_name_s startswith \"AUE_\" \n or header_event_name_s == \"PLAINTEXT_LOG_COLLECTION_EVENT\"\n or header_event_name_s == \"SYSTEM_PERFORMANCE_METRICS\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Telemetry'\n // Data Field Normalization\n //| project-rename \n // DvcIpAddr = input_host_ips_s,\n // DvcId = context_identity_claims_clientid_g\n | extend\n // Jamf Protect Alerts - Generic Information\n EventSeverity = case(\n input_match_severity_d == 0,\n \"Informational\",\n input_match_severity_d == 1,\n \"Low\",\n input_match_severity_d == 2,\n \"Medium\",\n input_match_severity_d == 3,\n \"High\",\n \"Informational\"\n ),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = coalesce(return_description_s, texts_s),\n // Jamf Protect Telemetry - Endpoint Information\n TargetModel = column_ifexists(\"metrics_hw_model_s\", \"\"),\n DvcOsVersion = column_ifexists(\"host_info_osversion_s\", \"\"),\n TargetHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"context_identity_claims_clientid_g\", \"\"),\n // Jamf Protect - Event Types\n EventType = case(\n header_event_name_s == \"AUE_add_to_group\",\n \"UserAddedToGroup\",\n header_event_name_s == \"AUE_AUDITCTL\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_AUDITON_SPOLICY\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_auth_user\",\n \"Elevate\",\n header_event_name_s == \"AUE_BIND\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_BIOS_FIRMWARE_VERSIONS\",\n \"SystemInformation\",\n header_event_name_s == \"AUE_CHDIR\",\n \"FolderMoved\",\n header_event_name_s == \"AUE_CHROOT\",\n \"FolderModified\",\n header_event_name_s == \"AUE_CONNECT\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_create_group\",\n \"GroupCreated\",\n header_event_name_s == \"AUE_create_user\",\n \"UserCreated\",\n header_event_name_s == \"AUE_delete_group\",\n \"GroupDeleted\",\n header_event_name_s == \"AUE_delete_user\",\n \"UserDeleted\",\n header_event_name_s == \"AUE_EXECVE\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_EXIT\",\n \"ProcessTerminated\",\n header_event_name_s == \"AUE_FORK\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_GETAUID\",\n \"\",\n header_event_name_s == \"AUE_KILL\",\n \"ProcessTerminated\",\n header_event_name_s == \"AUE_LISTEN\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_logout\",\n \"Logoff\",\n header_event_name_s == \"AUE_lw_login\",\n \"Logon\",\n header_event_name_s == \"AUE_MAC_SET_PROC\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_modify_group\",\n \"GroupModified\",\n header_event_name_s == \"AUE_modify_password\",\n \"PasswordChanged\",\n header_event_name_s == \"AUE_modify_user\",\n \"UserModified\",\n header_event_name_s == \"AUE_MOUNT\",\n \"VolumeMount\",\n header_event_name_s == \"AUE_openssh\",\n \"SshInitiated\",\n header_event_name_s == \"AUE_PIDFORTASK\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_POSIX_SPAWN\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_remove_from_group\",\n \"UserRemovedFromGroup\",\n header_event_name_s == \"AUE_SESSION_CLOSE\",\n \"Logoff\",\n header_event_name_s == \"AUE_SESSION_END\",\n \"Logoff\",\n header_event_name_s == \"AUE_SESSION_START\",\n \"Logon\",\n header_event_name_s == \"AUE_SESSION_UPDATE\",\n \"\",\n header_event_name_s == \"AUE_SETPRIORITY\",\n \"\",\n header_event_name_s == \"AUE_SETSOCKOPT\",\n \"\",\n header_event_name_s == \"AUE_SETTIMEOFDAY\",\n \"SystemChange\",\n header_event_name_s == \"AUE_shutdown\",\n \"ShutdownInitiated\",\n header_event_name_s == \"AUE_SOCKETPAIR\",\n \"\",\n header_event_name_s == \"AUE_ssauthint\",\n \"Elevate\",\n header_event_name_s == \"AUE_ssauthmech\",\n \"Elevate\",\n header_event_name_s == \"AUE_ssauthorize\",\n \"Elevate\",\n header_event_name_s == \"AUE_TASKFORPID\",\n \"\",\n header_event_name_s == \"AUE_TASKNAMEFORPID\",\n \"\",\n header_event_name_s == \"AUE_UNMOUNT\",\n \"VolumeUnmount\",\n header_event_name_s == \"AUE_WAIT4\",\n \"ProcessTerminated\",\n header_event_name_s == \"PLAINTEXT_LOG_COLLECTION_EVENT\",\n \"LogFileCollected\",\n header_event_name_s == \"SYSTEM_PERFORMANCE_METRICS\",\n \"SystemPerformanceMetrics\",\n \"Unknown\"\n ),\n // Jamf Protect Telemetry - Process\n ParentProcessName = column_ifexists(\"subject_responsible_process_name_s\", \"\"),\n ParentProcessId = column_ifexists(\"subject_responsible_process_id_d\", \"\"),\n ParentProcessGuid = column_ifexists(\"exec_chain_child_parent_uuid_g\", \"\"),\n TargetProcessName = column_ifexists(\"subject_process_name_s\", \"\"),\n TargetProcessId = column_ifexists(\"subject_process_id_d\", \"\"),\n TargetProcessGuid = column_ifexists(\"exec_chain_thread_uuid_g\", \"\"),\n TargetProcessSHA256 = todynamic(column_ifexists(\"subject_process_hash_s\", \"\")),\n TargetUserId = toreal(column_ifexists(\"subject_user_id_d\", \"\")),\n TargetUsername = tostring(column_ifexists(\"subject_user_name_s\", \"\")),\n TargetProcessCommandLine = column_ifexists(\"exec_args_args_compiled_s\", \"\"),\n ActorUsername = tostring(column_ifexists(\"subject_effective_user_name_s\", \"\")),\n ActorUserId = column_ifexists(\"subject_audit_user_name_s\", \"\"),\n //column_ifexists(\"application_name_s\", \"\"),\n //\n // Jamf Protect Telemetry - Audit/Group\n //\n GroupName = todynamic(column_ifexists(\"subject_group_name_s\", \"\")),\n // Jamf Protect Telemetry - Network\n DstIpAddr = column_ifexists(\"socket_inet_ip_address_s\", \"\"),\n DstPortNumber = column_ifexists(\"socket_inet_port_d\", \"\"),\n NetworkProtocolVersion = case(socket_inet_id_d == 128, \"IPV4\", socket_inet_id_d == 129, \"IPV6\", \"\"),\n SrcIpAddr = column_ifexists(\"subject_terminal_id_ip_address_s\", \"\"),\n //\n // Jamf Protect Telemetry - Binaries\n //\n // TargetBinaryFilePath = todynamic(Related_binaries[0].path),\n TargetBinarySHA256 = tostring(identity_cd_hash_s),\n // TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(identity_signer_type_d == 0, \"Developer\", identity_signer_type_d == 1, \"Apple\", \"\"),\n TargetBinarySigningTeamID = tostring(identity_team_id_s),\n TargetBinarySigningAppID = tostring(identity_signer_id_s),\n //\n // Jamf Protect Telemetry - Log File Collection\n //\n TargetFilePath = tostring(parse_json(path_s))\n | project-reorder\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventSeverity,\n EventResult,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOsVersion,\n DvcIpAddr,\n TargetModel,\n TargetUserId,\n TargetUsername,\n ParentProcessName,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA256,\n TargetProcessCommandLine,\n ActorUsername,\n ActorUserId,\n TargetBinarySHA256,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n GroupName,\n SrcIpAddr,\n DstIpAddr,\n DstPortNumber,\n NetworkProtocolVersion,\n TargetFilePath\n | project-away\n arguments_sflags_d,\n arguments_am_failure_d,\n arguments_am_success_d\n};\n//\n// Jamf Protect - Threat Events\n//\nlet JamfProtectThreatEvents_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Threat Events Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Threat Events Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventStartTime = column_ifexists(\"event_timestamp_t\", \"\"),\n EventResult=case(event_action_s == \"Blocked\", \"Blocked\", event_action_s == \"Detected\", \"Detected\", ''),\n EventReportUrl = column_ifexists(\"event_eventUrl_s\", \"\"),\n // Jamf Protect - Alert Details\n EventSeverity = case(event_severity_d == 2, \"Informational\", event_severity_d == 4, \"Low\", event_severity_d == 6, \"Medium\", event_severity_d == 8, \"High\", event_severity_d == 10, \"High\", \"Informational\"),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername=column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = column_ifexists(\"event_device_userDeviceName_s\", \"\"),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs=case(event_device_os_s has \"MAC_OS\", \"macOS\", event_device_os_s has \"IOS\", \"iOS\", event_device_os_s has \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType=case(event_device_os_s has \"MAC_OS\", \"Computer\", event_device_os_s has \"IOS\", \"Mobile Device\", event_device_os_s has \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery=column_ifexists('event_hostName_s', ''),\n DvcAction=case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName=column_ifexists('event_destination_name_s', ''),\n DstIpAddr=column_ifexists('event_destination_ip_s', ''),\n ThreatCategory=column_ifexists('event_eventType_description_s', ''),\n ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),\n // Jamf Protect - App Specific\n TargetFileName = column_ifexists(\"event_app_name_s\", \"\"),\n TargetFileSHA1 = column_ifexists(\"event_app_sha1_s\", \"\"),\n TargetFileSHA256 = column_ifexists(\"event_app_sha256_s\", \"\")\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventStartTime,\n EventResult,\n EventReportUrl,\n EventSeverity,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n ThreatCategory,\n DvcAction,\n ThreatOriginalRiskLevel,\n TargetFileName,\n TargetFileSHA1,\n TargetFileSHA256\n};\nunion isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectNetworkTraffic_view, JamfProtectTelemetry_view, JamfProtectThreatEvents_view\n", + "query": "let JamfProtectAlerts_view = view () {\njamfprotectalerts_CL\n| extend\n ActingProcessCreationTime = unixtime_seconds_todatetime(tolong(input.related.processes[array_length(input.related.processes) - 1].startTimestamp)),\n ParentProcessCreationTime = iff(\n array_length(input.related.processes) > 1, \n unixtime_seconds_todatetime(tolong(input.related.processes[0].startTimestamp)), \n datetime(null)\n ),\n TargetProcessCreationTime = unixtime_seconds_todatetime(todouble(input.related.processes[0].startTimestamp)),\n TargetUserId = coalesce(input.related.users[1].uid, input.related.users[0].uid),\n TargetUsername = coalesce(input.related.users[1].name, input.related.users[0].name)\n };\nlet JamfProtectUnifiedLog_view = view () {\njamfprotectunifiedlogs_CL\n| extend EventStartTime = unixtime_seconds_todatetime(tolong(input.match.event.timestamp))\n};\n//\n// Jamf Protect - Endpoint Telemetry\n//\nlet JamfProtectTelemetryv1_view = view () {\njamfprotecttelemetryv1_CL\n| extend\n EventStartTime = unixtime_seconds_todatetime(todouble(header.time_seconds_epoch)),\n EventResult = coalesce(return.description, texts)\n};\nlet JamfProtectTelemetryv2_view = view () {\njamfprotecttelemetryv2_CL\n// Generic Fields\n| extend\n EventExpanded = tostring(parse_json(event)[strcat_array(bag_keys(event), '.')]),\n eventTypeHuman = tostring(bag_keys(event)[0])\n| extend EventResult = iif((event[eventTypeHuman]['success'] == true), \"Success\", dynamic(null))\n| extend\n EventMessage = case(\n eventTypeHuman == \"authentication\",\n \"A user authentication happened\",\n eventTypeHuman == \"authorization_judgement\",\n \"A process has its rights petition judged\",\n eventTypeHuman == \"authorization_petition\",\n \"A process has its rights petition judged\",\n eventTypeHuman == \"bios_uefi\",\n \"Collection of bios and firmware data\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"Apple’s Background Task Manager notified that an item has been added\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"Apple’s Background Task Manager notified that an existing item has been removed\",\n eventTypeHuman == \"chroot\",\n \"Software has changed its apparent root directory in which it's actively operating out of\",\n eventTypeHuman == \"cs_invalidated\",\n \"The system detected that a process has had its code signature marked as invalid\",\n eventTypeHuman == \"exec\",\n \"A new process has been executed\",\n eventTypeHuman == \"kextload\",\n \"A kernel extension (kext) was loaded\",\n eventTypeHuman == \"kextunload\",\n \"A kernel extension (kext) was unloaded\",\n eventTypeHuman == \"login_login\",\n \"A user attempted to log in using /usr/bin/login\",\n eventTypeHuman == \"login_logout\",\n \"A user logged out from /usr/bin/login\",\n eventTypeHuman == \"lw_session_lock\",\n \"A user has locked the screen\",\n eventTypeHuman == \"lw_session_login\",\n \"A user has logged in via the Login Window\",\n eventTypeHuman == \"lw_session_logout\",\n \"A user has logged out of an active graphical session\",\n eventTypeHuman == \"lw_session_unlock\",\n \"A user has unlocked the screen from the Login Window\",\n eventTypeHuman == \"mount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"od_attribute_set\",\n \"Attribute set on user or group using Open Directory\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Attribute added to a user or group using Open Directory\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Attribute removed from a user or group using Open Directory\",\n eventTypeHuman == \"od_create_group\",\n \"A group has been created using Open Directory\",\n eventTypeHuman == \"od_create_user\",\n \"A user has been created using Open Directory\",\n eventTypeHuman == \"od_delete_group\",\n \"A group has been deleted using Open Directory\",\n eventTypeHuman == \"od_delete_user\",\n \"A user has been deleted using Open Directory\",\n eventTypeHuman == \"od_disable_user\",\n \"A user has been disabled using Open Directory\",\n eventTypeHuman == \"od_enable_user\",\n \"A user has been enabled using Open Directory\",\n eventTypeHuman == \"od_group_add\",\n \"A member has been added to a group using Open Directory\",\n eventTypeHuman == \"od_group_remove\",\n \"A member has been removed from a group using Open Directory\",\n eventTypeHuman == \"od_group_set\",\n \"A group has a member initialised or replaced using Open Directory\",\n eventTypeHuman == \"od_modify_password\",\n \"A user password is modified via Open Directory\",\n eventTypeHuman == \"openssh_login\",\n \"A user has logged into the system via OpenSSH\",\n eventTypeHuman == \"openssh_logout\",\n \"A user has logged out of an OpenSSH session\",\n eventTypeHuman == \"performance\",\n \"Collection of system performance data\",\n eventTypeHuman == \"profile_add\",\n \"A configuration profile is installed on the system\",\n eventTypeHuman == \"profile_remove\",\n \"A configuration profile is removed from the system\",\n eventTypeHuman == \"remount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"screenscharing_attach\",\n \"A screensharing session has attached to a graphical session\",\n eventTypeHuman == \"screenscharing_detach\",\n \"A screensharing session has detached from a graphical session\",\n eventTypeHuman == \"settime\",\n \"The system time was attempted to be set\",\n eventTypeHuman == \"su\",\n \"A user attempts to start a new shell using a substitute user identity\",\n eventTypeHuman == \"sudo\",\n \"A sudo attempt occured\",\n eventTypeHuman == \"unmount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"xp_malware_detected\",\n \"Apple’s XProtect detected malware on the system\",\n eventTypeHuman == \"xp_malware_remediated\",\n \"Apple’s XProtect remediated malware on the system\",\n eventTypeHuman == \"file_collection\",\n \"A crash or diagnostic file has been collected\",\n eventTypeHuman == \"log_collection\",\n \"Entries from a log file have been collected\",\n \"No reason yet defined for this event\"\n ),\n EventType = case(\n eventTypeHuman == \"authentication\",\n \"Logon\",\n eventTypeHuman == \"authorization_judgement\",\n \"ProcessCreated\",\n eventTypeHuman == \"authorization_petition\",\n \"ProcessCreated\",\n eventTypeHuman == \"bios_uefi\",\n \"Hardware\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"Create\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"Delete\",\n eventTypeHuman == \"chroot\",\n \"Set\",\n eventTypeHuman == \"cs_invalidated\",\n \"Other\",\n eventTypeHuman == \"exec\",\n \"ProcessCreated\",\n eventTypeHuman == \"kextload\",\n \"Create\",\n eventTypeHuman == \"kextunload\",\n \"Delete\",\n eventTypeHuman == \"login_login\",\n \"Logon\",\n eventTypeHuman == \"login_logout\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_lock\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_login\",\n \"Logon\",\n eventTypeHuman == \"lw_session_logout\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_unlock\",\n \"Logon\",\n eventTypeHuman == \"mount\",\n \"FileSystemMounted\",\n eventTypeHuman == \"od_attribute_set\",\n \"Set\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Create\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Delete\",\n eventTypeHuman == \"od_create_group\",\n \"GroupCreated\",\n eventTypeHuman == \"od_create_user\",\n \"UserCreated\",\n eventTypeHuman == \"od_delete_group\",\n \"GroupDeleted\",\n eventTypeHuman == \"od_delete_user\",\n \"UserDeleted\",\n eventTypeHuman == \"od_disable_user\",\n \"UserDisabled\",\n eventTypeHuman == \"od_enable_user\",\n \"UserEnabled\",\n eventTypeHuman == \"od_group_add\",\n \"UserAddedToGroup\",\n eventTypeHuman == \"od_group_remove\",\n \"UserRemovedFromGroup\",\n eventTypeHuman == \"od_group_set\",\n \"GroupModified\",\n eventTypeHuman == \"od_modify_password\",\n \"PasswordChanged\",\n eventTypeHuman == \"openssh_login\",\n \"Logon\",\n eventTypeHuman == \"openssh_logout\",\n \"Logoff\",\n eventTypeHuman == \"performance\",\n \"PerformanceData\",\n eventTypeHuman == \"profile_add\",\n \"Create\",\n eventTypeHuman == \"profile_remove\",\n \"Delete\",\n eventTypeHuman == \"remount\",\n \"FileSystemRemounted\",\n eventTypeHuman == \"screenscharing_attach\",\n \"Logon\",\n eventTypeHuman == \"screenscharing_detach\",\n \"Logoff\",\n eventTypeHuman == \"settime\",\n \"Set\",\n eventTypeHuman == \"su\",\n \"Elevate\",\n eventTypeHuman == \"sudo\",\n \"Elevate\",\n eventTypeHuman == \"unmount\",\n \"FileSystemUnmounted\",\n eventTypeHuman == \"xp_malware_detected\",\n \"MalwareDetected\",\n eventTypeHuman == \"xp_malware_remediated\",\n \"MalwareRemediated\",\n \"\"\n ),\n EventSubType = case(\n eventTypeHuman == \"authentication\",\n \"Interactive\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"btm\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"btm\",\n eventTypeHuman == \"chroot\",\n \"Directory\",\n eventTypeHuman == \"cs_invalidated\",\n \"Other\",\n eventTypeHuman == \"kextload\",\n \"System Settings\",\n eventTypeHuman == \"kextunload\",\n \"System Settings\",\n eventTypeHuman == \"login_login\",\n \"Interactive\",\n eventTypeHuman == \"login_logout\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_lock\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_login\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_logout\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_unlock\",\n \"Interactive\",\n eventTypeHuman == \"od_attribute_set\",\n \"Attribute\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Attribute\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Attribute\",\n eventTypeHuman == \"openssh_login\",\n \"Interactive\",\n eventTypeHuman == \"openssh_logout\",\n \"Interactive\",\n eventTypeHuman == \"profile_add\",\n \"Configuration Profile\",\n eventTypeHuman == \"profile_remove\",\n \"Configuration Profile\",\n eventTypeHuman == \"screenscharing_attach\",\n \"RemoteInteractive\",\n eventTypeHuman == \"screenscharing_detach\",\n \"RemoteInteractive\",\n eventTypeHuman == \"settime\",\n \"System Settings\",\n eventTypeHuman == \"su\",\n \"Interactive\",\n eventTypeHuman == \"sudo\",\n \"Interactive\",\n \"\"\n )\n// Jamf Protect Telemetry - Event Process\n| extend eventContext = \n iif(\n isnotempty(event[eventTypeHuman]['app']['audit_token']),\n event[eventTypeHuman]['app'],\n iif(\n isnotempty(event[eventTypeHuman]['target']['audit_token']),\n event[eventTypeHuman]['target'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['od']['audit_token']),\n event[eventTypeHuman]['data']['od'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['token']['audit_token']),\n event[eventTypeHuman]['data']['token'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['touchid']['audit_token']),\n event[eventTypeHuman]['data']['touchid'],\n iif(\n isnotempty(event[eventTypeHuman]['instigator']['audit_token']),\n event[eventTypeHuman]['instigator'],\n ['process']\n)\n)\n)\n)\n)\n)\n| extend\n TargetProcessName = tostring(eventContext.executable.path),\n TargetProcessId = tostring(eventContext.audit_token.pid),\n TargetProcessGuid = tostring(eventContext.audit_token.uuid),\n TargetProcessCreationTime = tostring(eventContext.start_time),\n TargetProcessSHA1 = tostring(eventContext.executable.sha1),\n TargetProcessSHA256 = tostring(eventContext.executable.sha256),\n TargetProcessCommandLine = event[eventTypeHuman]['args'],\n TargetProcessTTY = tostring(eventContext.tty.path),\n TargetBinarySigningAppID = tostring(eventContext.signing_id),\n TargetBinarySigningTeamID = tostring(eventContext.team_id),\n TargetBinaryCDHash = tostring(eventContext.cdhash),\n TargetBinaryIsESClient = tobool(eventContext.is_es_client),\n TargetBinaryIsPlatformBinary = tobool(eventContext.is_platform_binary),\n TargetUserId = tostring(eventContext.audit_token.euid),\n ActingProcessId = tostring(eventContext.parent_audit_token.pid),\n ActingProcessGuid = tostring(eventContext.parent_audit_token.uuid),\n ActorUserId = tostring(eventContext.parent_audit_token.euid),\n ParentProcessId = tostring(eventContext.responsible_audit_token.pid),\n ParentProcessGuid = tostring(eventContext.responsible_audit_token.uuid)\n// Jamf Protect Telemetry - Revealing Code Signing flags\n| extend TargetProcessCodesignFlags = \n iif(isnotempty(eventContext.codesigning_flags),\n bag_pack(\n \"CS_VALID\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000001) > 0, true, false),\n \"CS_ADHOC\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000002) > 0, true, false),\n \"CS_GET_TASK_ALLOW\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000004) > 0, true, false),\n \"CS_INSTALLER\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000008) > 0, true, false),\n \"CS_FORCED_LV\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000010) > 0, true, false),\n \"CS_INVALID_ALLOWED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000020) > 0, true, false),\n \"CS_HARD\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000100) > 0, true, false),\n \"CS_KILL\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000200) > 0, true, false),\n \"CS_CHECK_EXPIRATION\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000400) > 0, true, false),\n \"CS_RESTRICT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000800) > 0, true, false),\n \"CS_ENFORCEMENT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00001000) > 0, true, false),\n \"CS_REQUIRE_LV\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00002000) > 0, true, false),\n \"CS_ENTITLEMENTS_VALIDATED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00004000) > 0, true, false),\n \"CS_NVRAM_UNRESTRICTED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00008000) > 0, true, false),\n \"CS_RUNTIME\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00010000) > 0, true, false),\n \"CS_LINKER_SIGNED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x20000) > 0, true, false),\n \"CS_EXEC_SET_HARD\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00100000) > 0, true, false),\n \"CS_EXEC_SET_KILL\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00200000) > 0, true, false),\n \"CS_EXEC_SET_ENFORCEMENT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00400000) > 0, true, false),\n \"CS_EXEC_INHERIT_SIP\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00800000) > 0, true, false),\n \"CS_KILLED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x01000000) > 0, true, false),\n \"CS_DYLD_PLATFORM\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x02000000) > 0, true, false),\n \"CS_PLATFORM_BINARY\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x04000000) > 0, true, false),\n \"CS_PLATFORM_PATH\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x08000000) > 0, true, false),\n \"CS_DEBUGGED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x10000000) > 0, true, false),\n \"CS_SIGNED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x20000000) > 0, true, false),\n \"CS_DEV_CODE\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x40000000) > 0, true, false),\n \"CS_DATAVAULT_CONTROLLER\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x80000000) > 0, true, false)\n ), \"\")\n// Event Specific - authentication\n| extend TargetUsername =\n iif(\n isnotempty(event[eventTypeHuman]['username']),\n event[eventTypeHuman]['username'],\n iif(\n isnotempty(event[eventTypeHuman]['to_username']),\n event[eventTypeHuman]['to_username'],\n iif(\n isnotempty(event[eventTypeHuman]['account_name']),\n event[eventTypeHuman]['account_name'],\n iif(\n isnotempty(event[eventTypeHuman]['user_name']),\n event[eventTypeHuman]['user_name'],\n iif(\n isnotempty(event[eventTypeHuman]['authentication_username']),\n event[eventTypeHuman]['authentication_username'],\n \"\"\n)\n)\n)\n)\n)\n// Event Specific - authentication\n| extend ActorUsername = \n iif(\n isnotempty(event[eventTypeHuman]['from_username']),\n event[eventTypeHuman]['from_username'],\n iif(\n isnotempty(event[eventTypeHuman]['session_username']),\n event[eventTypeHuman]['session_username'],\n \"\"\n)\n)\n| extend Authentication = iif(\n eventTypeHuman == \"authentication\",\n bag_pack(\n \"authentication_method\",\n iff(isnotempty(event[eventTypeHuman].data), tostring(bag_keys(event[eventTypeHuman].data)[0]), \"\")\n),\n dynamic(null)\n )\n// Event Specific - bios_uefi\n| extend HardwareInformation = iif(\n eventTypeHuman == \"bios_uefi\",\n bag_pack(\n \"host_architecture\",\n iff(isnotempty(event[eventTypeHuman].architecture), event[eventTypeHuman].architecture, \"\"),\n \"firmware_version\",\n iff(isnotempty(event[eventTypeHuman].bios.['firmware-version']), event[eventTypeHuman].bios.['firmware-version'], \"\"),\n \"system_firmware_version\",\n iff(isnotempty(event[eventTypeHuman].bios.['system-firmware-version']), event[eventTypeHuman].bios.['system-firmware-version'], \"\")\n),\n dynamic(null)\n )\n// Event Specific - btm_launch_item_add & btm_launch_item_remove\n| extend BtmItem = iif(\n eventTypeHuman in (\"btm_launch_item_add\", \"btm_launch_item_remove\", \"remount\"),\n bag_pack(\n \"btm_executable_path\",\n iff(isnotempty(event[eventTypeHuman].executable_path), event[eventTypeHuman].executable_path, \"\"),\n \"btm_item_app_url\",\n iff(isnotempty(event[eventTypeHuman].item.app_url), event[eventTypeHuman].item.app_url, \"\"),\n \"btm_item_url\",\n iff(isnotempty(event[eventTypeHuman].item.item_url), event[eventTypeHuman].item.item_url, \"\"),\n \"btm_item_managed\",\n iff(isnotempty(event[eventTypeHuman].item.managed), event[eventTypeHuman].item.managed, \"\"),\n \"btm_item_legacy\",\n iff(isnotempty(event[eventTypeHuman].item.legacy), event[eventTypeHuman].item.legacy, \"\"),\n \"btm_item_uid\",\n iff(isnotempty(event[eventTypeHuman].item.uid), event[eventTypeHuman].item.uid, \"\"),\n \"btm_item_type\",\n iff(\n isnotempty(event[eventTypeHuman].item.item_type),\n case(\n event[eventTypeHuman].item.item_type == 0,\n \"UserItem\",\n event[eventTypeHuman].item.item_type == 1,\n \"App\",\n event[eventTypeHuman].item.item_type == 2,\n \"LoginItem\",\n event[eventTypeHuman].item.item_type == 3,\n \"LaunchAgent\",\n event[eventTypeHuman].item.item_type == 4,\n \"LaunchDaemon\",\n \"Unknown\"\n),\n \"\"\n)\n),\n dynamic(null)\n )\n// Event Specific - chroot\n| extend Chroot = iif(\n eventTypeHuman == \"chroot\",\n bag_pack(\n \"apparent_root_directory\",\n iff(isnotempty(event[eventTypeHuman].target), event[eventTypeHuman].target.path, \"\"),\n \"stats\",\n iff(isnotempty(event[eventTypeHuman].target.stat), event[eventTypeHuman].target.stat, \"\")\n),\n dynamic(null)\n )\n// Event Specific - cs_invalidated\n// Event Specific - exec\n// Event Specific - kextload & kextunload\n| extend KernelExtension = iif(\n eventTypeHuman in (\"kextload\", \"kextunload\"),\n bag_pack(\n \"kext_identifier\",\n iff(isnotempty(event[eventTypeHuman].identifier), event[eventTypeHuman].identifier, \"\")\n),\n dynamic(null)\n )\n// Event Specific - lw_session_lock & lw_session_unlock & lw_session_login & lw_session_logout\n| extend LoginWindowSession = iif(\n eventTypeHuman in (\"lw_session_lock\", \"lw_session_unlock\", \"lw_session_login\", \"lw_session_logout\"),\n bag_pack(\n \"graphical_session_id\",\n iff(isnotempty(event[eventTypeHuman].graphical_session_id), event[eventTypeHuman].graphical_session_id, \"\")\n),\n dynamic(null)\n )\n// Event Specific - mount & remount & unmount\n| extend FileSystem = iif(\n eventTypeHuman in (\"mount\", \"unmount\", \"remount\"),\n bag_pack(\n \"volume_device_name\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_mntfromname), event[eventTypeHuman].statfs.f_mntfromname, \"\"),\n \"volume_mount_name\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_mntonname), event[eventTypeHuman].statfs.f_mntonname, \"\"),\n \"volume_file_system_type\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_fstypename), event[eventTypeHuman].statfs.f_fstypename, \"\"),\n \"volume_size\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_bsize), event[eventTypeHuman].statfs.f_bsize, \"\")\n),\n dynamic(null)\n )\n// Event Specific - od_attribute_set & od_attribute_value_add & od_attribute_value_remove & od_create_group & od_create_user & od_delete_group & od_delete_user & od_disable_user & od_enable_user\n| extend OpenDirectory = iif(\n eventTypeHuman in (\"od_attribute_set\", \"od_attribute_value_add\", \"od_attribute_value_remove\", \"od_create_group\", \"od_create_user\", \"od_delete_group\", \"od_delete_user\", \"od_disable_user\", \"od_enable_user\"),\n bag_pack(\n \"group_name\",\n iff(isnotempty(event[eventTypeHuman].group_name), event[eventTypeHuman].group_name, \"\"),\n \"member_array\",\n iff(isnotempty(event[eventTypeHuman].members.member_array), event[eventTypeHuman].members.member_array, \"\"),\n \"member_value\",\n iff(isnotempty(event[eventTypeHuman].member.member_value), event[eventTypeHuman].member.member_value, \"\"),\n \"user_name\",\n iff(isnotempty(event[eventTypeHuman].user_name), event[eventTypeHuman].user_name, \"\"),\n \"account_name\",\n iff(isnotempty(event[eventTypeHuman].account_name), event[eventTypeHuman].account_name, \"\"),\n \"db_path\",\n iff(isnotempty(event[eventTypeHuman].db_path), event[eventTypeHuman].db_path, \"\"),\n \"record_name\",\n iff(isnotempty(event[eventTypeHuman].record_name), event[eventTypeHuman].record_name, \"\"),\n \"attribute_name\",\n iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, \"\"),\n \"attribute_value\",\n iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, \"\"),\n \"node_name\",\n iff(isnotempty(event[eventTypeHuman].node_name), event[eventTypeHuman].node_name, \"\")\n),\n dynamic(null)\n )\n// Event Specific - openssh_login & openssh_logout\n| extend SSHContext = iif(\n eventTypeHuman in (\"openssh_login\", \"openssh_logout\"),\n bag_pack(\n \"source_address_type\", \n iff(\n isnotempty(event[eventTypeHuman].source_address_type),\n case(\n event[eventTypeHuman].source_address_type == 0,\n \"Unknown\",\n event[eventTypeHuman].source_address_type == 1,\n \"IPv4\",\n event[eventTypeHuman].source_address_type == 2,\n \"IPv6\",\n event[eventTypeHuman].source_address_type == 3,\n \"UNIX Socket\",\n \"Unknown\"\n),\n \"\" \n),\n \"result_type\", \n iff(\n isnotempty(event[eventTypeHuman].result_type),\n case(\n event[eventTypeHuman].result_type == 0,\n \"Exceeded maximum attempts\",\n event[eventTypeHuman].result_type == 1,\n \"Denied by root\",\n event[eventTypeHuman].result_type == 2,\n \"Success\",\n event[eventTypeHuman].result_type == 3,\n \"No reason\",\n event[eventTypeHuman].result_type == 4,\n \"Password\",\n event[eventTypeHuman].result_type == 5,\n \"kbdint\",\n event[eventTypeHuman].result_type == 6,\n \"Public key\",\n event[eventTypeHuman].result_type == 7,\n \"Host based\",\n event[eventTypeHuman].result_type == 8,\n \"GSS API\",\n event[eventTypeHuman].result_type == 9,\n \"Invalid user\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null) \n )\n// Event Specific - performance\n// Event Specific - profile_add & profile_remove\n| extend Profile = iif(\n eventTypeHuman in (\"profile_add\", \"profile_remove\"),\n bag_pack(\n \"profile_scope\",\n iff(isnotempty(event[eventTypeHuman].profile.scope), event[eventTypeHuman].profile.scope, \"\"),\n \"profile_identifier\",\n iff(isnotempty(event[eventTypeHuman].profile.identifier), event[eventTypeHuman].profile.identifiery, \"\"),\n \"profile_uuid\",\n iff(isnotempty(event[eventTypeHuman].profile.uuid), event[eventTypeHuman].profile.uuid, \"\"),\n \"profile_display_name\",\n iff(isnotempty(event[eventTypeHuman].profile.display_name), event[eventTypeHuman].profile.display_name, \"\"),\n \"profile_organization\",\n iff(isnotempty(event[eventTypeHuman].profile.organization), event[eventTypeHuman].profile.organization, \"\"),\n \"profile_is_updated\",\n iff(isnotempty(event[eventTypeHuman].is_update), event[eventTypeHuman].is_update, \"\"),\n \"profile_install_source\", \n iff(\n isnotempty(event[eventTypeHuman].profile.install_source),\n case(\n event[eventTypeHuman].profile.install_source == 0,\n \"mdm\",\n event[eventTypeHuman].profile.install_source == 1,\n \"manual\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null)\n )\n// Event Specific - screenscharing_attach & screensharing_detach\n| extend Screensharing = iif(\n eventTypeHuman in (\"screensharing_attach\", \"screensharing_detach\"),\n bag_pack(\n \"existing_session\",\n iff(isnotempty(event[eventTypeHuman].existing_session), event[eventTypeHuman].existing_session, \"\"),\n \"graphical_session_id\",\n iff(isnotempty(event[eventTypeHuman].graphical_authentication_username), event[eventTypeHuman].graphical_authentication_username, \"\"),\n \"session_username\",\n iff(isnotempty(event[eventTypeHuman].session_username), event[eventTypeHuman].session_username, \"\"),\n \"viewer_appleid\",\n iff(isnotempty(event[eventTypeHuman].viewer_appleid), event[eventTypeHuman].viewer_appleid, \"\"),\n \"authentication_type\",\n iff(isnotempty(event[eventTypeHuman].authentication_type), event[eventTypeHuman].authentication_type, \"\"),\n \"source_address\",\n iff(isnotempty(event[eventTypeHuman].source_address), event[eventTypeHuman].source_address, \"\"),\n \"source_address_type\", \n iff(\n isnotempty(event[eventTypeHuman].source_address_type),\n case(\n event[eventTypeHuman].source_address_type == 0,\n \"Unknown\",\n event[eventTypeHuman].source_address_type == 1,\n \"IPv4\",\n event[eventTypeHuman].source_address_type == 2,\n \"IPv6\",\n event[eventTypeHuman].source_address_type == 3,\n \"UNIX Socket\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null)\n )\n// Event Specific - su\n| extend Su = iif(\n eventTypeHuman == \"su\",\n bag_pack(\n \"username\",\n iff(isnotempty(event[eventTypeHuman].username), event[eventTypeHuman].username, \"\"),\n \"uid\",\n iff(isnotempty(event[eventTypeHuman].uid), event[eventTypeHuman].uid, \"\"),\n \"args\",\n iff(isnotempty(event[eventTypeHuman].argv), event[eventTypeHuman].argv, \"\"),\n \"env_vars\",\n iff(isnotempty(event[eventTypeHuman].env), event[eventTypeHuman].env, \"\"),\n \"env_count\",\n iff(isnotempty(event[eventTypeHuman].env_count), event[eventTypeHuman].env_count, \"\"),\n \"from_username\",\n iff(isnotempty(event[eventTypeHuman].from_username), event[eventTypeHuman].from_username, \"\"),\n \"to_username\",\n iff(isnotempty(event[eventTypeHuman].to_username), event[eventTypeHuman].to_username, \"\"),\n \"failure_message\",\n iff(isnotempty(event[eventTypeHuman].failure_reason), event[eventTypeHuman].failure_reason, \"\")\n),\n dynamic(null)\n )\n// Event Specific - sudo\n| extend Sudo = iif(\n eventTypeHuman == \"sudo\",\n bag_pack(\n \"TargetProcessCommandLine\",\n iff(isnotempty(event[eventTypeHuman].command), event[eventTypeHuman].command, \"\"),\n \"attribute_name\",\n iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, \"\"),\n \"attribute_value\",\n iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, \"\")\n),\n dynamic(null)\n )\n// Event Specific - xp_malware_detected & xp_malware_remediated\n| extend Xprotect = iif(\n eventTypeHuman in (\"xp_malware_detected\", \"xp_malware_remediated\"),\n bag_pack(\n \"detected_path\",\n iff(isnotempty(event[eventTypeHuman].detected_path), event[eventTypeHuman].detected_path, \"\"),\n \"remediated_path\",\n iff(isnotempty(event[eventTypeHuman].remediated_path), event[eventTypeHuman].remediated_path, \"\"),\n \"malware_identifier\",\n iff(isnotempty(event[eventTypeHuman].malware_identifier), event[eventTypeHuman].malware_identifier, \"\"),\n \"signature_version\",\n iff(isnotempty(event[eventTypeHuman].signature_version), event[eventTypeHuman].signature_version, \"\")\n),\n dynamic(null)\n )\n| project-away\naction,\nevent,\nprocess\n};\n//\n// Jamf Protect - Network Traffic\n//\nlet JamfProtectNetworkTraffic_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Network Traffic Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Network Traffic Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventType = \"query\",\n EventSubType = \"request\",\n EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),\n EventResult = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Prevented\", ''),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername = column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs = case(event_device_osType_s == \"MAC_OS\", \"macOS\", event_device_osType_s == \"IOS\", \"iOS\", event_device_osType_s == \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType = case(event_device_osType_s == \"MAC_OS\", \"Computer\", event_device_osType_s == \"IOS\", \"Mobile Device\", event_device_osType_s == \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery = column_ifexists('event_hostName_s', ''),\n DvcAction = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName = column_ifexists('event_domain_s', ''),\n DstIpAddr = column_ifexists('event_destination_ips_s', ''),\n ThreatCategory = column_ifexists('event_eventType_description_s', ''),\n DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),\n DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),\n ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventType,\n EventSubType,\n EventStartTime,\n EventResult,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n DvcOs,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n DnsQueryTypeName,\n DvcAction,\n DnsResponseName,\n ThreatOriginalRiskLevel\n};\n// //\n// // Jamf Protect - Threat Events\n// //\nlet JamfProtectThreatEvents_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Threat Events Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Threat Events Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventStartTime = column_ifexists(\"event_timestamp_t\", \"\"),\n EventResult=case(event_action_s == \"Blocked\", \"Blocked\", event_action_s == \"Detected\", \"Detected\", ''),\n EventReportUrl = column_ifexists(\"event_eventUrl_s\", \"\"),\n // Jamf Protect - Alert Details\n EventSeverity = case(event_severity_d == 2, \"Informational\", event_severity_d == 4, \"Low\", event_severity_d == 6, \"Medium\", event_severity_d == 8, \"High\", event_severity_d == 10, \"High\", \"Informational\"),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername=column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = column_ifexists(\"event_device_userDeviceName_s\", \"\"),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs=case(event_device_os_s has \"MAC_OS\", \"macOS\", event_device_os_s has \"IOS\", \"iOS\", event_device_os_s has \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType=case(event_device_os_s has \"MAC_OS\", \"Computer\", event_device_os_s has \"IOS\", \"Mobile Device\", event_device_os_s has \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery=column_ifexists('event_hostName_s', ''),\n DvcAction=case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName=column_ifexists('event_destination_name_s', ''),\n DstIpAddr=column_ifexists('event_destination_ip_s', ''),\n ThreatCategory=column_ifexists('event_eventType_description_s', ''),\n ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),\n // Jamf Protect - App Specific\n TargetFileName = column_ifexists(\"event_app_name_s\", \"\"),\n TargetFileSHA1 = column_ifexists(\"event_app_sha1_s\", \"\"),\n TargetFileSHA256 = column_ifexists(\"event_app_sha256_s\", \"\")\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventStartTime,\n EventResult,\n EventReportUrl,\n EventSeverity,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n ThreatCategory,\n DvcAction,\n ThreatOriginalRiskLevel,\n TargetFileName,\n TargetFileSHA1,\n TargetFileSHA256\n};\nunion isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectTelemetryv1_view, JamfProtectTelemetryv2_view, JamfProtectNetworkTraffic_view, JamfProtectThreatEvents_view\n", "functionParameters": "", "version": 2, "tags": [ @@ -497,8 +2133,8 @@ "contentId": "[variables('parserObject1').parserContentId1]", "contentKind": "Parser", "displayName": "JamfProtect", - "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '3.1.0')))]", - "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '3.1.0')))]", + "contentProductId": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '3.2.0')))]", + "id": "[concat(take(variables('_solutionId'),50),'-','pr','-', uniqueString(concat(variables('_solutionId'),'-','Parser','-',variables('parserObject1').parserContentId1,'-', '3.2.0')))]", "version": "[variables('parserObject1').parserVersion1]" } }, @@ -512,7 +2148,7 @@ "displayName": "JamfProtect", "category": "Microsoft Sentinel Parser", "functionAlias": "JamfProtect", - "query": "let JamfProtectAlerts_view = view () {\n jamfprotect_CL\n| where topicType_s == \"alert\"\n and input_eventType_s <> \"GPUnifiedLogEvent\"\n and isnotempty(input_match_severity_d)\n// JSON Parsing at earliest stage\n| extend \n Related_users = parse_json(input_related_users_s),\n Related_files = parse_json(input_related_files_s),\n Related_binaries = parse_json(input_related_binaries_s),\n Related_groups = parse_json(input_related_groups_s),\n Related_processes = parse_json(input_related_processes_s),\n Match_facts = parse_json(input_match_facts_s),\n Match_tags = parse_json(input_match_tags_s),\n Match_actions = parse_json(input_match_actions_s),\n Match_context = parse_json(input_match_context_s),\n Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)\n// ASIM - Common Fields\n| extend EventVendor = 'Jamf'\n| extend EventProduct = 'Jamf Protect - Alerts'\n| project-rename\n EventOriginalUid = input_match_uuid_g\n| extend\n // Jamf Protect - Common Fields\n EventType = case(\n input_eventType_s == \"GPClickEvent\",\n \"Click\",\n input_eventType_s == \"GPDownloadEvent\",\n \"Download\",\n input_eventType_s == \"GPFSEvent\",\n \"FileSystem\",\n input_eventType_s == \"GPProcessEvent\",\n \"Process\",\n input_eventType_s == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input_eventType_s == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input_eventType_s == \"GPMRTEvent\",\n \"MRT\",\n input_eventType_s == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input_eventType_s == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input_eventType_s == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input_eventType_s == \"GPUSBEvent\",\n \"USB\",\n input_eventType_s == \"auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),\n EventMessage = coalesce(Match_facts[1].name, Match_facts[0].name),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = case(Match_actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n EventProductVersion = column_ifexists(\"input_host_protectVersion_s\", \"\"),\n //\n // Jamf Protect - Alert details\n //\n EventSeverity = case(input_match_severity_d == 0, \"Informational\", input_match_severity_d == 1, \"Low\", input_match_severity_d == 2, \"Medium\", input_match_severity_d == 3, \"High\", \"Informational\"),\n EventMatch = column_ifexists(\"input_match_event_matchValue_s\", \"\"),\n EventMatchType = column_ifexists(\"input_match_event_matchType_s\", \"\"),\n EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", EventOriginalUid),\n //\n // Jamf Protect - Source User\n SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect - Source Device Hostnames\n //\n TargetHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"input_host_provisioningUDID_g\", \"\"),\n DvcOs=\"macOS\",\n SrcDeviceType=\"Computer\",\n //\n // Jamf Protect Alerts - Process\n //\n ProcessEventType = case(input_match_event_type_d == 0, \"None\", input_match_event_type_d == 1, \"Create\", input_match_event_type_d == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input_match_event_subType_d == 7, \"Exec\", input_match_event_subType_d == 1, \"Fork\", input_match_event_subType_d == 23, \"Execve\", input_match_event_subType_d == 43190, \"Posix Spawn\", \"\"),\n ActingProcessName = tostring(Related_processes[array_length(Related_processes) - 1].path),\n ActingProcessCreationTime = format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[array_length(Related_processes) - 1].startTimestamp)), 'HH:mm:ss'),\n ActingProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].responsiblePID)),\n ActingProcessGuid = tostring(Related_processes[array_length(Related_processes) - 1].uuid),\n ParentProcessName = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].path), \"\"),\n ParentProcessCreationTime = iff(array_length(Related_processes) > 1, format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[1].startTimestamp)), 'HH:mm:ss'), \"\"),\n ParentProcessId = iff(array_length(Related_processes) > 1, toreal(Related_processes[1].pid), double(null)),\n ParentProcessGuid = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].uuid), \"\"),\n TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),\n TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),\n TargetProcessGuid = tostring(Related_processes[0].uuid),\n TargetProcessSHA1 = Related_binaries[0].sha1hex,\n TargetProcessSHA256 = Related_binaries[0].sha256hex,\n TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),\n TargetProcessCommandLine = column_ifexists(\"input_match_event_process_args_s\", \"\"),\n TargetProcessCurrentDirectory = column_ifexists(\"input_match_event_process_path_s\", \"\"),\n //TargetProcessStatusCode = column_ifexists(Related_processes[0].exitCode, \"\"),\n TargetUserId = toreal(coalesce(Related_users[1].uid, Related_processes[0].uid)),\n TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].uid)),\n //\n // Jamf Protect Alerts - Files\n //\n TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),\n TargetFileSHA1 = Related_files[0].sha1hex,\n TargetFileSHA256 = Related_files[0].sha256hex,\n TargetFileSize = Related_files[0].size,\n TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, \"Apple\", Related_files[0].signingInfo.signerType == 1, \"App Store\", Related_files[0].signingInfo.signerType == 2, \"Developer\", Related_files[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,\n TargetFileIsDownload = case(Related_files[0].isDownload == \"true\", \"true\", Related_files[0].isDownload == \"false\", \"false\", \"\"),\n TargetFileIsAppBundle = case(Related_files[0].isAppBundle == \"true\", \"true\", Related_files[0].isAppBundle == \"false\", \"false\", \"\"),\n TargetFileIsDirectory = case(Related_files[0].isDirectory == \"true\", \"true\", Related_files[0].isDirectory == \"false\", \"false\", \"\"),\n TargetFileIsScreenshot = case(Related_files[0].isScreenShot == \"true\", \"true\", Related_files[0].isScreenShot == \"false\", \"false\", \"\"),\n //\n // Jamf Protect Alerts - Binaries\n TargetBinaryFilePath = Related_binaries[0].path,\n TargetBinarySHA1 = tostring(Related_binaries[0].sha1hex),\n TargetBinarySHA256 = tostring(Related_binaries[0].sha256hex),\n TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(Related_binaries[0].signingInfo.signerType == 0, \"Apple\", Related_binaries[0].signingInfo.signerType == 1, \"App Store\", Related_binaries[0].signingInfo.signerType == 2, \"Developer\", Related_binaries[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_binaries[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetBinarySigningTeamID = tostring(Related_binaries[0].signingInfo.teamid),\n TargetBinarySigningAppID = tostring(Related_binaries[0].signingInfo.appid)\n| project-reorder\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventMessage,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventProductVersion,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ActingProcessName,\n ActingProcessCreationTime,\n ActingProcessId,\n ActingProcessGuid,\n ParentProcessName,\n ParentProcessCreationTime,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessSHA256,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n //TargetProcessStatusCode,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n TargetBinaryFilePath,\n TargetBinarySHA1,\n TargetBinarySHA256,\n TargetBinarySigningInfoMessage,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event_*\n| project-keep\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventMessage,\n EventProductVersion,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ActingProcessName,\n ActingProcessCreationTime,\n ActingProcessId,\n ActingProcessGuid,\n ParentProcessName,\n ParentProcessCreationTime,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessSHA256,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n //TargetProcessStatusCode,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n TargetBinaryFilePath,\n TargetBinarySHA1,\n TargetBinarySHA256,\n TargetBinarySigningInfoMessage,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event_*\n};\n//\n// Jamf Protect - Unified Logs\n//\nlet JamfProtectUnifiedLog_view = view () {\n jamfprotect_CL\n | where input_eventType_s == \"GPUnifiedLogEvent\"\n and isnotempty(input_match_severity_d)\n // JSON Parsing at earliest stage\n | extend \n Related_users = parse_json(input_related_users_s),\n Related_files = parse_json(input_related_files_s),\n Related_binaries = parse_json(input_related_binaries_s),\n Related_groups = parse_json(input_related_groups_s),\n Related_processes = parse_json(input_related_processes_s),\n Match_facts = parse_json(input_match_facts_s),\n Match_tags = parse_json(input_match_tags_s),\n Match_actions = parse_json(input_match_actions_s),\n Match_context = parse_json(input_match_context_s),\n Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s)\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Unified Log'\n | project-rename\n EventOriginalUid = input_match_uuid_g\n | extend\n // Jamf Protect - Common Fields\n EventType = case(\n input_eventType_s == \"GPClickEvent\",\n \"Click\",\n input_eventType_s == \"GPDownloadEvent\",\n \"Download\",\n input_eventType_s == \"GPFSEvent\",\n \"FileSystem\",\n input_eventType_s == \"GPProcessEvent\",\n \"Process\",\n input_eventType_s == \"GPKeylogRegisterEvent\",\n \"Keylog\",\n input_eventType_s == \"GPGatekeeperEvent\",\n \"Gatekeeper\",\n input_eventType_s == \"GPMRTEvent\",\n \"MRT\",\n input_eventType_s == \"GPPreventedExecutionEvent\",\n \"ProcessDenied\",\n input_eventType_s == \"GPThreatMatchExecEvent\",\n \"ProcessPrevented\",\n input_eventType_s == \"GPUnifiedLogEvent\",\n \"UnifiedLog\",\n input_eventType_s == \"GPUSBEvent\",\n \"USB\",\n input_eventType_s == \"Auth-mount\",\n \"UsbBlock\",\n \"Unknown\"\n ),\n EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = case(Match_actions has \"Prevented\", \"Prevented\", \"Allowed\"),\n //\n // Jamf Protect - Unified Logs details\n //\n EventSeverity = case(input_match_severity_d == 0, \"Informational\", input_match_severity_d == 1, \"Low\", input_match_severity_d == 2, \"Medium\", input_match_severity_d == 3, \"High\", \"Informational\"),\n EventMatch = column_ifexists(\"input_match_event_matchValue_s\", \"\"),\n EventMatchType = column_ifexists(\"input_match_event_matchType_s\", \"\"),\n EventReportUrl = strcat(\"https://\", context_identity_claims_hd_s, \".jamfcloud.com/Alerts/\", EventOriginalUid),\n //\n // Jamf Protect - Source User\n SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect - Source Device Hostnames\n //\n TargetHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcHostname = column_ifexists(\"input_host_hostname_s\", \"\"),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"input_host_provisioningUDID_g\", \"\"),\n DvcOs=\"macOS\",\n SrcDeviceType=\"Computer\",\n //\n // Jamf Protect Unified Logs - Process\n //\n //ParentProcessName = coalesce(input_match_event_process_ppid_d, parse_json('input_related_processes_s')[0].ppid), //column_ifexists(\"exec_chain_child_parent_path_s\", \"\"), coalesce('input.match.event.process.ppid', mvindex('input.related.processes{}.ppid', 0))\n ProcessEventType = case(input_match_event_type_d == 0, \"None\", input_match_event_type_d == 1, \"Create\", input_match_event_type_d == 2, \"Exit\", \"\"),\n ProcessEventSubType = case(input_match_event_subType_d == 7, \"Exec\", input_match_event_subType_d == 1, \"Fork\", input_match_event_subType_d == 23, \"Execve\", input_match_event_subType_d == 43190, \"Posix Spawn\", \"\"),\n ParentProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].ppid)),\n ParentProcessGuid = tostring(coalesce(input_match_event_process_pgid_d, toreal(Related_processes[0].pgid))),\n TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name),\n TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)),\n TargetProcessGuid = tostring(Related_processes[0].uuid),\n TargetProcessSHA1 = Related_binaries[0].sha1hex,\n TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)),\n TargetProcessCommandLine = column_ifexists(\"input_match_event_process_args_s\", \"\"),\n TargetProcessCurrentDirectory = column_ifexists(\"input_match_event_process_path_s\", \"\"),\n TargetUserId = toreal(coalesce(Related_users[1].uid, Related_users[0].uid)),\n TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)),\n //\n // Jamf Protect Unified Logs - Files\n //\n TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)),\n TargetFileSHA1 = Related_files[0].sha1hex,\n TargetFileSHA256 = Related_files[0].sha256hex,\n TargetFileSize = Related_files[0].size,\n TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage,\n TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, \"Apple\", Related_files[0].signingInfo.signerType == 1, \"App Store\", Related_files[0].signingInfo.signerType == 2, \"Developer\", Related_files[0].signingInfo.signerType == 3, \"Ad Hoc\", Related_files[0].signingInfo.signerType == 4, \"Unsigned\", \"\"),\n TargetFileSigningTeamID = Related_files[0].signingInfo.teamid,\n TargetFileIsDownload = case(Related_files[0].isDownload == \"true\", \"true\", Related_files[0].isDownload == \"false\", \"false\", \"\"),\n TargetFileIsAppBundle = case(Related_files[0].isAppBundle == \"true\", \"true\", Related_files[0].isAppBundle == \"false\", \"false\", \"\"),\n TargetFileIsDirectory = case(Related_files[0].isDirectory == \"true\", \"true\", Related_files[0].isDirectory == \"false\", \"false\", \"\"),\n TargetFileIsScreenshot = case(Related_files[0].isScreenShot == \"true\", \"true\", Related_files[0].isScreenShot == \"false\", \"false\", \"\")\n | project-reorder\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags\n | project-keep\n TimeGenerated,\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventDescription,\n EventSeverity,\n EventMatch,\n EventMatchType,\n EventResult,\n EventReportUrl,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOs,\n DvcIpAddr,\n SrcDeviceType,\n SrcUsername,\n ProcessEventType,\n ProcessEventSubType,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA1,\n TargetProcessCreationTime,\n TargetProcessCommandLine,\n TargetProcessCurrentDirectory,\n TargetUsername,\n TargetUserId,\n TargetFilePath,\n TargetFileSHA1,\n TargetFileSHA256,\n TargetFileSize,\n TargetFileSigningInfoMessage,\n TargetFileSignerType,\n TargetFileSigningTeamID,\n TargetFileIsAppBundle,\n TargetFileIsDirectory,\n TargetFileIsDownload,\n TargetFileIsScreenshot,\n Related_users,\n Related_files,\n Related_binaries,\n Related_groups,\n Related_processes,\n Match_event_process_signing,\n Match_facts,\n Match_actions,\n Match_tags,\n *input_match_event*\n};\n//\n// Jamf Protect - Network Traffic\n//\nlet JamfProtectNetworkTraffic_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Network Traffic Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Network Traffic Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventType = \"query\",\n EventSubType = \"request\",\n EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),\n EventResult = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Prevented\", ''),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername = column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs = case(event_device_osType_s == \"MAC_OS\", \"macOS\", event_device_osType_s == \"IOS\", \"iOS\", event_device_osType_s == \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType = case(event_device_osType_s == \"MAC_OS\", \"Computer\", event_device_osType_s == \"IOS\", \"Mobile Device\", event_device_osType_s == \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery = column_ifexists('event_hostName_s', ''),\n DvcAction = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName = column_ifexists('event_domain_s', ''),\n DstIpAddr = column_ifexists('event_destination_ips_s', ''),\n ThreatCategory = column_ifexists('event_eventType_description_s', ''),\n DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),\n DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),\n ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventType,\n EventSubType,\n EventStartTime,\n EventResult,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n DvcOs,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n DnsQueryTypeName,\n DvcAction,\n DnsResponseName,\n ThreatOriginalRiskLevel\n};\n//\n// Jamf Protect - Endpoint Telemetry\n//\nlet JamfProtectTelemetry_view = view () {\n jamfprotect_CL\n | where header_event_name_s startswith \"AUE_\" \n or header_event_name_s == \"PLAINTEXT_LOG_COLLECTION_EVENT\"\n or header_event_name_s == \"SYSTEM_PERFORMANCE_METRICS\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Telemetry'\n // Data Field Normalization\n //| project-rename \n // DvcIpAddr = input_host_ips_s,\n // DvcId = context_identity_claims_clientid_g\n | extend\n // Jamf Protect Alerts - Generic Information\n EventSeverity = case(\n input_match_severity_d == 0,\n \"Informational\",\n input_match_severity_d == 1,\n \"Low\",\n input_match_severity_d == 2,\n \"Medium\",\n input_match_severity_d == 3,\n \"High\",\n \"Informational\"\n ),\n EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)),\n EventResult = coalesce(return_description_s, texts_s),\n // Jamf Protect Telemetry - Endpoint Information\n TargetModel = column_ifexists(\"metrics_hw_model_s\", \"\"),\n DvcOsVersion = column_ifexists(\"host_info_osversion_s\", \"\"),\n TargetHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"input_host_ips_s\", \"\"),\n DvcId = column_ifexists(\"context_identity_claims_clientid_g\", \"\"),\n // Jamf Protect - Event Types\n EventType = case(\n header_event_name_s == \"AUE_add_to_group\",\n \"UserAddedToGroup\",\n header_event_name_s == \"AUE_AUDITCTL\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_AUDITON_SPOLICY\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_auth_user\",\n \"Elevate\",\n header_event_name_s == \"AUE_BIND\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_BIOS_FIRMWARE_VERSIONS\",\n \"SystemInformation\",\n header_event_name_s == \"AUE_CHDIR\",\n \"FolderMoved\",\n header_event_name_s == \"AUE_CHROOT\",\n \"FolderModified\",\n header_event_name_s == \"AUE_CONNECT\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_create_group\",\n \"GroupCreated\",\n header_event_name_s == \"AUE_create_user\",\n \"UserCreated\",\n header_event_name_s == \"AUE_delete_group\",\n \"GroupDeleted\",\n header_event_name_s == \"AUE_delete_user\",\n \"UserDeleted\",\n header_event_name_s == \"AUE_EXECVE\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_EXIT\",\n \"ProcessTerminated\",\n header_event_name_s == \"AUE_FORK\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_GETAUID\",\n \"\",\n header_event_name_s == \"AUE_KILL\",\n \"ProcessTerminated\",\n header_event_name_s == \"AUE_LISTEN\",\n \"EndpointNetworkSession\",\n header_event_name_s == \"AUE_logout\",\n \"Logoff\",\n header_event_name_s == \"AUE_lw_login\",\n \"Logon\",\n header_event_name_s == \"AUE_MAC_SET_PROC\",\n \"AuditEvent\",\n header_event_name_s == \"AUE_modify_group\",\n \"GroupModified\",\n header_event_name_s == \"AUE_modify_password\",\n \"PasswordChanged\",\n header_event_name_s == \"AUE_modify_user\",\n \"UserModified\",\n header_event_name_s == \"AUE_MOUNT\",\n \"VolumeMount\",\n header_event_name_s == \"AUE_openssh\",\n \"SshInitiated\",\n header_event_name_s == \"AUE_PIDFORTASK\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_POSIX_SPAWN\",\n \"ProcessCreated\",\n header_event_name_s == \"AUE_remove_from_group\",\n \"UserRemovedFromGroup\",\n header_event_name_s == \"AUE_SESSION_CLOSE\",\n \"Logoff\",\n header_event_name_s == \"AUE_SESSION_END\",\n \"Logoff\",\n header_event_name_s == \"AUE_SESSION_START\",\n \"Logon\",\n header_event_name_s == \"AUE_SESSION_UPDATE\",\n \"\",\n header_event_name_s == \"AUE_SETPRIORITY\",\n \"\",\n header_event_name_s == \"AUE_SETSOCKOPT\",\n \"\",\n header_event_name_s == \"AUE_SETTIMEOFDAY\",\n \"SystemChange\",\n header_event_name_s == \"AUE_shutdown\",\n \"ShutdownInitiated\",\n header_event_name_s == \"AUE_SOCKETPAIR\",\n \"\",\n header_event_name_s == \"AUE_ssauthint\",\n \"Elevate\",\n header_event_name_s == \"AUE_ssauthmech\",\n \"Elevate\",\n header_event_name_s == \"AUE_ssauthorize\",\n \"Elevate\",\n header_event_name_s == \"AUE_TASKFORPID\",\n \"\",\n header_event_name_s == \"AUE_TASKNAMEFORPID\",\n \"\",\n header_event_name_s == \"AUE_UNMOUNT\",\n \"VolumeUnmount\",\n header_event_name_s == \"AUE_WAIT4\",\n \"ProcessTerminated\",\n header_event_name_s == \"PLAINTEXT_LOG_COLLECTION_EVENT\",\n \"LogFileCollected\",\n header_event_name_s == \"SYSTEM_PERFORMANCE_METRICS\",\n \"SystemPerformanceMetrics\",\n \"Unknown\"\n ),\n // Jamf Protect Telemetry - Process\n ParentProcessName = column_ifexists(\"subject_responsible_process_name_s\", \"\"),\n ParentProcessId = column_ifexists(\"subject_responsible_process_id_d\", \"\"),\n ParentProcessGuid = column_ifexists(\"exec_chain_child_parent_uuid_g\", \"\"),\n TargetProcessName = column_ifexists(\"subject_process_name_s\", \"\"),\n TargetProcessId = column_ifexists(\"subject_process_id_d\", \"\"),\n TargetProcessGuid = column_ifexists(\"exec_chain_thread_uuid_g\", \"\"),\n TargetProcessSHA256 = todynamic(column_ifexists(\"subject_process_hash_s\", \"\")),\n TargetUserId = toreal(column_ifexists(\"subject_user_id_d\", \"\")),\n TargetUsername = tostring(column_ifexists(\"subject_user_name_s\", \"\")),\n TargetProcessCommandLine = column_ifexists(\"exec_args_args_compiled_s\", \"\"),\n ActorUsername = tostring(column_ifexists(\"subject_effective_user_name_s\", \"\")),\n ActorUserId = column_ifexists(\"subject_audit_user_name_s\", \"\"),\n //column_ifexists(\"application_name_s\", \"\"),\n //\n // Jamf Protect Telemetry - Audit/Group\n //\n GroupName = todynamic(column_ifexists(\"subject_group_name_s\", \"\")),\n // Jamf Protect Telemetry - Network\n DstIpAddr = column_ifexists(\"socket_inet_ip_address_s\", \"\"),\n DstPortNumber = column_ifexists(\"socket_inet_port_d\", \"\"),\n NetworkProtocolVersion = case(socket_inet_id_d == 128, \"IPV4\", socket_inet_id_d == 129, \"IPV6\", \"\"),\n SrcIpAddr = column_ifexists(\"subject_terminal_id_ip_address_s\", \"\"),\n //\n // Jamf Protect Telemetry - Binaries\n //\n // TargetBinaryFilePath = todynamic(Related_binaries[0].path),\n TargetBinarySHA256 = tostring(identity_cd_hash_s),\n // TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage,\n TargetbinarySignerType = case(identity_signer_type_d == 0, \"Developer\", identity_signer_type_d == 1, \"Apple\", \"\"),\n TargetBinarySigningTeamID = tostring(identity_team_id_s),\n TargetBinarySigningAppID = tostring(identity_signer_id_s),\n //\n // Jamf Protect Telemetry - Log File Collection\n //\n TargetFilePath = tostring(parse_json(path_s))\n | project-reorder\n EventStartTime,\n EventVendor,\n EventProduct,\n EventType,\n EventSeverity,\n EventResult,\n TargetHostname,\n DvcHostname,\n DvcId,\n DvcOsVersion,\n DvcIpAddr,\n TargetModel,\n TargetUserId,\n TargetUsername,\n ParentProcessName,\n ParentProcessId,\n ParentProcessGuid,\n TargetProcessName,\n TargetProcessId,\n TargetProcessGuid,\n TargetProcessSHA256,\n TargetProcessCommandLine,\n ActorUsername,\n ActorUserId,\n TargetBinarySHA256,\n TargetbinarySignerType,\n TargetBinarySigningTeamID,\n TargetBinarySigningAppID,\n GroupName,\n SrcIpAddr,\n DstIpAddr,\n DstPortNumber,\n NetworkProtocolVersion,\n TargetFilePath\n | project-away\n arguments_sflags_d,\n arguments_am_failure_d,\n arguments_am_success_d\n};\n//\n// Jamf Protect - Threat Events\n//\nlet JamfProtectThreatEvents_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Threat Events Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Threat Events Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventStartTime = column_ifexists(\"event_timestamp_t\", \"\"),\n EventResult=case(event_action_s == \"Blocked\", \"Blocked\", event_action_s == \"Detected\", \"Detected\", ''),\n EventReportUrl = column_ifexists(\"event_eventUrl_s\", \"\"),\n // Jamf Protect - Alert Details\n EventSeverity = case(event_severity_d == 2, \"Informational\", event_severity_d == 4, \"Low\", event_severity_d == 6, \"Medium\", event_severity_d == 8, \"High\", event_severity_d == 10, \"High\", \"Informational\"),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername=column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = column_ifexists(\"event_device_userDeviceName_s\", \"\"),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs=case(event_device_os_s has \"MAC_OS\", \"macOS\", event_device_os_s has \"IOS\", \"iOS\", event_device_os_s has \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType=case(event_device_os_s has \"MAC_OS\", \"Computer\", event_device_os_s has \"IOS\", \"Mobile Device\", event_device_os_s has \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery=column_ifexists('event_hostName_s', ''),\n DvcAction=case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName=column_ifexists('event_destination_name_s', ''),\n DstIpAddr=column_ifexists('event_destination_ip_s', ''),\n ThreatCategory=column_ifexists('event_eventType_description_s', ''),\n ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),\n // Jamf Protect - App Specific\n TargetFileName = column_ifexists(\"event_app_name_s\", \"\"),\n TargetFileSHA1 = column_ifexists(\"event_app_sha1_s\", \"\"),\n TargetFileSHA256 = column_ifexists(\"event_app_sha256_s\", \"\")\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventStartTime,\n EventResult,\n EventReportUrl,\n EventSeverity,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n ThreatCategory,\n DvcAction,\n ThreatOriginalRiskLevel,\n TargetFileName,\n TargetFileSHA1,\n TargetFileSHA256\n};\nunion isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectNetworkTraffic_view, JamfProtectTelemetry_view, JamfProtectThreatEvents_view\n", + "query": "let JamfProtectAlerts_view = view () {\njamfprotectalerts_CL\n| extend\n ActingProcessCreationTime = unixtime_seconds_todatetime(tolong(input.related.processes[array_length(input.related.processes) - 1].startTimestamp)),\n ParentProcessCreationTime = iff(\n array_length(input.related.processes) > 1, \n unixtime_seconds_todatetime(tolong(input.related.processes[0].startTimestamp)), \n datetime(null)\n ),\n TargetProcessCreationTime = unixtime_seconds_todatetime(todouble(input.related.processes[0].startTimestamp)),\n TargetUserId = coalesce(input.related.users[1].uid, input.related.users[0].uid),\n TargetUsername = coalesce(input.related.users[1].name, input.related.users[0].name)\n };\nlet JamfProtectUnifiedLog_view = view () {\njamfprotectunifiedlogs_CL\n| extend EventStartTime = unixtime_seconds_todatetime(tolong(input.match.event.timestamp))\n};\n//\n// Jamf Protect - Endpoint Telemetry\n//\nlet JamfProtectTelemetryv1_view = view () {\njamfprotecttelemetryv1_CL\n| extend\n EventStartTime = unixtime_seconds_todatetime(todouble(header.time_seconds_epoch)),\n EventResult = coalesce(return.description, texts)\n};\nlet JamfProtectTelemetryv2_view = view () {\njamfprotecttelemetryv2_CL\n// Generic Fields\n| extend\n EventExpanded = tostring(parse_json(event)[strcat_array(bag_keys(event), '.')]),\n eventTypeHuman = tostring(bag_keys(event)[0])\n| extend EventResult = iif((event[eventTypeHuman]['success'] == true), \"Success\", dynamic(null))\n| extend\n EventMessage = case(\n eventTypeHuman == \"authentication\",\n \"A user authentication happened\",\n eventTypeHuman == \"authorization_judgement\",\n \"A process has its rights petition judged\",\n eventTypeHuman == \"authorization_petition\",\n \"A process has its rights petition judged\",\n eventTypeHuman == \"bios_uefi\",\n \"Collection of bios and firmware data\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"Apple’s Background Task Manager notified that an item has been added\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"Apple’s Background Task Manager notified that an existing item has been removed\",\n eventTypeHuman == \"chroot\",\n \"Software has changed its apparent root directory in which it's actively operating out of\",\n eventTypeHuman == \"cs_invalidated\",\n \"The system detected that a process has had its code signature marked as invalid\",\n eventTypeHuman == \"exec\",\n \"A new process has been executed\",\n eventTypeHuman == \"kextload\",\n \"A kernel extension (kext) was loaded\",\n eventTypeHuman == \"kextunload\",\n \"A kernel extension (kext) was unloaded\",\n eventTypeHuman == \"login_login\",\n \"A user attempted to log in using /usr/bin/login\",\n eventTypeHuman == \"login_logout\",\n \"A user logged out from /usr/bin/login\",\n eventTypeHuman == \"lw_session_lock\",\n \"A user has locked the screen\",\n eventTypeHuman == \"lw_session_login\",\n \"A user has logged in via the Login Window\",\n eventTypeHuman == \"lw_session_logout\",\n \"A user has logged out of an active graphical session\",\n eventTypeHuman == \"lw_session_unlock\",\n \"A user has unlocked the screen from the Login Window\",\n eventTypeHuman == \"mount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"od_attribute_set\",\n \"Attribute set on user or group using Open Directory\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Attribute added to a user or group using Open Directory\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Attribute removed from a user or group using Open Directory\",\n eventTypeHuman == \"od_create_group\",\n \"A group has been created using Open Directory\",\n eventTypeHuman == \"od_create_user\",\n \"A user has been created using Open Directory\",\n eventTypeHuman == \"od_delete_group\",\n \"A group has been deleted using Open Directory\",\n eventTypeHuman == \"od_delete_user\",\n \"A user has been deleted using Open Directory\",\n eventTypeHuman == \"od_disable_user\",\n \"A user has been disabled using Open Directory\",\n eventTypeHuman == \"od_enable_user\",\n \"A user has been enabled using Open Directory\",\n eventTypeHuman == \"od_group_add\",\n \"A member has been added to a group using Open Directory\",\n eventTypeHuman == \"od_group_remove\",\n \"A member has been removed from a group using Open Directory\",\n eventTypeHuman == \"od_group_set\",\n \"A group has a member initialised or replaced using Open Directory\",\n eventTypeHuman == \"od_modify_password\",\n \"A user password is modified via Open Directory\",\n eventTypeHuman == \"openssh_login\",\n \"A user has logged into the system via OpenSSH\",\n eventTypeHuman == \"openssh_logout\",\n \"A user has logged out of an OpenSSH session\",\n eventTypeHuman == \"performance\",\n \"Collection of system performance data\",\n eventTypeHuman == \"profile_add\",\n \"A configuration profile is installed on the system\",\n eventTypeHuman == \"profile_remove\",\n \"A configuration profile is removed from the system\",\n eventTypeHuman == \"remount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"screenscharing_attach\",\n \"A screensharing session has attached to a graphical session\",\n eventTypeHuman == \"screenscharing_detach\",\n \"A screensharing session has detached from a graphical session\",\n eventTypeHuman == \"settime\",\n \"The system time was attempted to be set\",\n eventTypeHuman == \"su\",\n \"A user attempts to start a new shell using a substitute user identity\",\n eventTypeHuman == \"sudo\",\n \"A sudo attempt occured\",\n eventTypeHuman == \"unmount\",\n \"A file system has been mounted\",\n eventTypeHuman == \"xp_malware_detected\",\n \"Apple’s XProtect detected malware on the system\",\n eventTypeHuman == \"xp_malware_remediated\",\n \"Apple’s XProtect remediated malware on the system\",\n eventTypeHuman == \"file_collection\",\n \"A crash or diagnostic file has been collected\",\n eventTypeHuman == \"log_collection\",\n \"Entries from a log file have been collected\",\n \"No reason yet defined for this event\"\n ),\n EventType = case(\n eventTypeHuman == \"authentication\",\n \"Logon\",\n eventTypeHuman == \"authorization_judgement\",\n \"ProcessCreated\",\n eventTypeHuman == \"authorization_petition\",\n \"ProcessCreated\",\n eventTypeHuman == \"bios_uefi\",\n \"Hardware\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"Create\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"Delete\",\n eventTypeHuman == \"chroot\",\n \"Set\",\n eventTypeHuman == \"cs_invalidated\",\n \"Other\",\n eventTypeHuman == \"exec\",\n \"ProcessCreated\",\n eventTypeHuman == \"kextload\",\n \"Create\",\n eventTypeHuman == \"kextunload\",\n \"Delete\",\n eventTypeHuman == \"login_login\",\n \"Logon\",\n eventTypeHuman == \"login_logout\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_lock\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_login\",\n \"Logon\",\n eventTypeHuman == \"lw_session_logout\",\n \"Logoff\",\n eventTypeHuman == \"lw_session_unlock\",\n \"Logon\",\n eventTypeHuman == \"mount\",\n \"FileSystemMounted\",\n eventTypeHuman == \"od_attribute_set\",\n \"Set\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Create\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Delete\",\n eventTypeHuman == \"od_create_group\",\n \"GroupCreated\",\n eventTypeHuman == \"od_create_user\",\n \"UserCreated\",\n eventTypeHuman == \"od_delete_group\",\n \"GroupDeleted\",\n eventTypeHuman == \"od_delete_user\",\n \"UserDeleted\",\n eventTypeHuman == \"od_disable_user\",\n \"UserDisabled\",\n eventTypeHuman == \"od_enable_user\",\n \"UserEnabled\",\n eventTypeHuman == \"od_group_add\",\n \"UserAddedToGroup\",\n eventTypeHuman == \"od_group_remove\",\n \"UserRemovedFromGroup\",\n eventTypeHuman == \"od_group_set\",\n \"GroupModified\",\n eventTypeHuman == \"od_modify_password\",\n \"PasswordChanged\",\n eventTypeHuman == \"openssh_login\",\n \"Logon\",\n eventTypeHuman == \"openssh_logout\",\n \"Logoff\",\n eventTypeHuman == \"performance\",\n \"PerformanceData\",\n eventTypeHuman == \"profile_add\",\n \"Create\",\n eventTypeHuman == \"profile_remove\",\n \"Delete\",\n eventTypeHuman == \"remount\",\n \"FileSystemRemounted\",\n eventTypeHuman == \"screenscharing_attach\",\n \"Logon\",\n eventTypeHuman == \"screenscharing_detach\",\n \"Logoff\",\n eventTypeHuman == \"settime\",\n \"Set\",\n eventTypeHuman == \"su\",\n \"Elevate\",\n eventTypeHuman == \"sudo\",\n \"Elevate\",\n eventTypeHuman == \"unmount\",\n \"FileSystemUnmounted\",\n eventTypeHuman == \"xp_malware_detected\",\n \"MalwareDetected\",\n eventTypeHuman == \"xp_malware_remediated\",\n \"MalwareRemediated\",\n \"\"\n ),\n EventSubType = case(\n eventTypeHuman == \"authentication\",\n \"Interactive\",\n eventTypeHuman == \"btm_launch_item_add\",\n \"btm\",\n eventTypeHuman == \"btm_launch_item_remove\",\n \"btm\",\n eventTypeHuman == \"chroot\",\n \"Directory\",\n eventTypeHuman == \"cs_invalidated\",\n \"Other\",\n eventTypeHuman == \"kextload\",\n \"System Settings\",\n eventTypeHuman == \"kextunload\",\n \"System Settings\",\n eventTypeHuman == \"login_login\",\n \"Interactive\",\n eventTypeHuman == \"login_logout\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_lock\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_login\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_logout\",\n \"Interactive\",\n eventTypeHuman == \"lw_session_unlock\",\n \"Interactive\",\n eventTypeHuman == \"od_attribute_set\",\n \"Attribute\",\n eventTypeHuman == \"od_attribute_value_add\",\n \"Attribute\",\n eventTypeHuman == \"od_attribute_value_remove\",\n \"Attribute\",\n eventTypeHuman == \"openssh_login\",\n \"Interactive\",\n eventTypeHuman == \"openssh_logout\",\n \"Interactive\",\n eventTypeHuman == \"profile_add\",\n \"Configuration Profile\",\n eventTypeHuman == \"profile_remove\",\n \"Configuration Profile\",\n eventTypeHuman == \"screenscharing_attach\",\n \"RemoteInteractive\",\n eventTypeHuman == \"screenscharing_detach\",\n \"RemoteInteractive\",\n eventTypeHuman == \"settime\",\n \"System Settings\",\n eventTypeHuman == \"su\",\n \"Interactive\",\n eventTypeHuman == \"sudo\",\n \"Interactive\",\n \"\"\n )\n// Jamf Protect Telemetry - Event Process\n| extend eventContext = \n iif(\n isnotempty(event[eventTypeHuman]['app']['audit_token']),\n event[eventTypeHuman]['app'],\n iif(\n isnotempty(event[eventTypeHuman]['target']['audit_token']),\n event[eventTypeHuman]['target'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['od']['audit_token']),\n event[eventTypeHuman]['data']['od'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['token']['audit_token']),\n event[eventTypeHuman]['data']['token'],\n iif(\n isnotempty(event[eventTypeHuman]['data']['touchid']['audit_token']),\n event[eventTypeHuman]['data']['touchid'],\n iif(\n isnotempty(event[eventTypeHuman]['instigator']['audit_token']),\n event[eventTypeHuman]['instigator'],\n ['process']\n)\n)\n)\n)\n)\n)\n| extend\n TargetProcessName = tostring(eventContext.executable.path),\n TargetProcessId = tostring(eventContext.audit_token.pid),\n TargetProcessGuid = tostring(eventContext.audit_token.uuid),\n TargetProcessCreationTime = tostring(eventContext.start_time),\n TargetProcessSHA1 = tostring(eventContext.executable.sha1),\n TargetProcessSHA256 = tostring(eventContext.executable.sha256),\n TargetProcessCommandLine = event[eventTypeHuman]['args'],\n TargetProcessTTY = tostring(eventContext.tty.path),\n TargetBinarySigningAppID = tostring(eventContext.signing_id),\n TargetBinarySigningTeamID = tostring(eventContext.team_id),\n TargetBinaryCDHash = tostring(eventContext.cdhash),\n TargetBinaryIsESClient = tobool(eventContext.is_es_client),\n TargetBinaryIsPlatformBinary = tobool(eventContext.is_platform_binary),\n TargetUserId = tostring(eventContext.audit_token.euid),\n ActingProcessId = tostring(eventContext.parent_audit_token.pid),\n ActingProcessGuid = tostring(eventContext.parent_audit_token.uuid),\n ActorUserId = tostring(eventContext.parent_audit_token.euid),\n ParentProcessId = tostring(eventContext.responsible_audit_token.pid),\n ParentProcessGuid = tostring(eventContext.responsible_audit_token.uuid)\n// Jamf Protect Telemetry - Revealing Code Signing flags\n| extend TargetProcessCodesignFlags = \n iif(isnotempty(eventContext.codesigning_flags),\n bag_pack(\n \"CS_VALID\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000001) > 0, true, false),\n \"CS_ADHOC\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000002) > 0, true, false),\n \"CS_GET_TASK_ALLOW\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000004) > 0, true, false),\n \"CS_INSTALLER\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000008) > 0, true, false),\n \"CS_FORCED_LV\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000010) > 0, true, false),\n \"CS_INVALID_ALLOWED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000020) > 0, true, false),\n \"CS_HARD\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000100) > 0, true, false),\n \"CS_KILL\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000200) > 0, true, false),\n \"CS_CHECK_EXPIRATION\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000400) > 0, true, false),\n \"CS_RESTRICT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00000800) > 0, true, false),\n \"CS_ENFORCEMENT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00001000) > 0, true, false),\n \"CS_REQUIRE_LV\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00002000) > 0, true, false),\n \"CS_ENTITLEMENTS_VALIDATED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00004000) > 0, true, false),\n \"CS_NVRAM_UNRESTRICTED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00008000) > 0, true, false),\n \"CS_RUNTIME\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00010000) > 0, true, false),\n \"CS_LINKER_SIGNED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x20000) > 0, true, false),\n \"CS_EXEC_SET_HARD\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00100000) > 0, true, false),\n \"CS_EXEC_SET_KILL\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00200000) > 0, true, false),\n \"CS_EXEC_SET_ENFORCEMENT\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00400000) > 0, true, false),\n \"CS_EXEC_INHERIT_SIP\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x00800000) > 0, true, false),\n \"CS_KILLED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x01000000) > 0, true, false),\n \"CS_DYLD_PLATFORM\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x02000000) > 0, true, false),\n \"CS_PLATFORM_BINARY\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x04000000) > 0, true, false),\n \"CS_PLATFORM_PATH\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x08000000) > 0, true, false),\n \"CS_DEBUGGED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x10000000) > 0, true, false),\n \"CS_SIGNED\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x20000000) > 0, true, false),\n \"CS_DEV_CODE\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x40000000) > 0, true, false),\n \"CS_DATAVAULT_CONTROLLER\",\n iff(binary_and(toint(eventContext.codesigning_flags), 0x80000000) > 0, true, false)\n ), \"\")\n// Event Specific - authentication\n| extend TargetUsername =\n iif(\n isnotempty(event[eventTypeHuman]['username']),\n event[eventTypeHuman]['username'],\n iif(\n isnotempty(event[eventTypeHuman]['to_username']),\n event[eventTypeHuman]['to_username'],\n iif(\n isnotempty(event[eventTypeHuman]['account_name']),\n event[eventTypeHuman]['account_name'],\n iif(\n isnotempty(event[eventTypeHuman]['user_name']),\n event[eventTypeHuman]['user_name'],\n iif(\n isnotempty(event[eventTypeHuman]['authentication_username']),\n event[eventTypeHuman]['authentication_username'],\n \"\"\n)\n)\n)\n)\n)\n// Event Specific - authentication\n| extend ActorUsername = \n iif(\n isnotempty(event[eventTypeHuman]['from_username']),\n event[eventTypeHuman]['from_username'],\n iif(\n isnotempty(event[eventTypeHuman]['session_username']),\n event[eventTypeHuman]['session_username'],\n \"\"\n)\n)\n| extend Authentication = iif(\n eventTypeHuman == \"authentication\",\n bag_pack(\n \"authentication_method\",\n iff(isnotempty(event[eventTypeHuman].data), tostring(bag_keys(event[eventTypeHuman].data)[0]), \"\")\n),\n dynamic(null)\n )\n// Event Specific - bios_uefi\n| extend HardwareInformation = iif(\n eventTypeHuman == \"bios_uefi\",\n bag_pack(\n \"host_architecture\",\n iff(isnotempty(event[eventTypeHuman].architecture), event[eventTypeHuman].architecture, \"\"),\n \"firmware_version\",\n iff(isnotempty(event[eventTypeHuman].bios.['firmware-version']), event[eventTypeHuman].bios.['firmware-version'], \"\"),\n \"system_firmware_version\",\n iff(isnotempty(event[eventTypeHuman].bios.['system-firmware-version']), event[eventTypeHuman].bios.['system-firmware-version'], \"\")\n),\n dynamic(null)\n )\n// Event Specific - btm_launch_item_add & btm_launch_item_remove\n| extend BtmItem = iif(\n eventTypeHuman in (\"btm_launch_item_add\", \"btm_launch_item_remove\", \"remount\"),\n bag_pack(\n \"btm_executable_path\",\n iff(isnotempty(event[eventTypeHuman].executable_path), event[eventTypeHuman].executable_path, \"\"),\n \"btm_item_app_url\",\n iff(isnotempty(event[eventTypeHuman].item.app_url), event[eventTypeHuman].item.app_url, \"\"),\n \"btm_item_url\",\n iff(isnotempty(event[eventTypeHuman].item.item_url), event[eventTypeHuman].item.item_url, \"\"),\n \"btm_item_managed\",\n iff(isnotempty(event[eventTypeHuman].item.managed), event[eventTypeHuman].item.managed, \"\"),\n \"btm_item_legacy\",\n iff(isnotempty(event[eventTypeHuman].item.legacy), event[eventTypeHuman].item.legacy, \"\"),\n \"btm_item_uid\",\n iff(isnotempty(event[eventTypeHuman].item.uid), event[eventTypeHuman].item.uid, \"\"),\n \"btm_item_type\",\n iff(\n isnotempty(event[eventTypeHuman].item.item_type),\n case(\n event[eventTypeHuman].item.item_type == 0,\n \"UserItem\",\n event[eventTypeHuman].item.item_type == 1,\n \"App\",\n event[eventTypeHuman].item.item_type == 2,\n \"LoginItem\",\n event[eventTypeHuman].item.item_type == 3,\n \"LaunchAgent\",\n event[eventTypeHuman].item.item_type == 4,\n \"LaunchDaemon\",\n \"Unknown\"\n),\n \"\"\n)\n),\n dynamic(null)\n )\n// Event Specific - chroot\n| extend Chroot = iif(\n eventTypeHuman == \"chroot\",\n bag_pack(\n \"apparent_root_directory\",\n iff(isnotempty(event[eventTypeHuman].target), event[eventTypeHuman].target.path, \"\"),\n \"stats\",\n iff(isnotempty(event[eventTypeHuman].target.stat), event[eventTypeHuman].target.stat, \"\")\n),\n dynamic(null)\n )\n// Event Specific - cs_invalidated\n// Event Specific - exec\n// Event Specific - kextload & kextunload\n| extend KernelExtension = iif(\n eventTypeHuman in (\"kextload\", \"kextunload\"),\n bag_pack(\n \"kext_identifier\",\n iff(isnotempty(event[eventTypeHuman].identifier), event[eventTypeHuman].identifier, \"\")\n),\n dynamic(null)\n )\n// Event Specific - lw_session_lock & lw_session_unlock & lw_session_login & lw_session_logout\n| extend LoginWindowSession = iif(\n eventTypeHuman in (\"lw_session_lock\", \"lw_session_unlock\", \"lw_session_login\", \"lw_session_logout\"),\n bag_pack(\n \"graphical_session_id\",\n iff(isnotempty(event[eventTypeHuman].graphical_session_id), event[eventTypeHuman].graphical_session_id, \"\")\n),\n dynamic(null)\n )\n// Event Specific - mount & remount & unmount\n| extend FileSystem = iif(\n eventTypeHuman in (\"mount\", \"unmount\", \"remount\"),\n bag_pack(\n \"volume_device_name\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_mntfromname), event[eventTypeHuman].statfs.f_mntfromname, \"\"),\n \"volume_mount_name\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_mntonname), event[eventTypeHuman].statfs.f_mntonname, \"\"),\n \"volume_file_system_type\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_fstypename), event[eventTypeHuman].statfs.f_fstypename, \"\"),\n \"volume_size\",\n iff(isnotempty(event[eventTypeHuman].statfs.f_bsize), event[eventTypeHuman].statfs.f_bsize, \"\")\n),\n dynamic(null)\n )\n// Event Specific - od_attribute_set & od_attribute_value_add & od_attribute_value_remove & od_create_group & od_create_user & od_delete_group & od_delete_user & od_disable_user & od_enable_user\n| extend OpenDirectory = iif(\n eventTypeHuman in (\"od_attribute_set\", \"od_attribute_value_add\", \"od_attribute_value_remove\", \"od_create_group\", \"od_create_user\", \"od_delete_group\", \"od_delete_user\", \"od_disable_user\", \"od_enable_user\"),\n bag_pack(\n \"group_name\",\n iff(isnotempty(event[eventTypeHuman].group_name), event[eventTypeHuman].group_name, \"\"),\n \"member_array\",\n iff(isnotempty(event[eventTypeHuman].members.member_array), event[eventTypeHuman].members.member_array, \"\"),\n \"member_value\",\n iff(isnotempty(event[eventTypeHuman].member.member_value), event[eventTypeHuman].member.member_value, \"\"),\n \"user_name\",\n iff(isnotempty(event[eventTypeHuman].user_name), event[eventTypeHuman].user_name, \"\"),\n \"account_name\",\n iff(isnotempty(event[eventTypeHuman].account_name), event[eventTypeHuman].account_name, \"\"),\n \"db_path\",\n iff(isnotempty(event[eventTypeHuman].db_path), event[eventTypeHuman].db_path, \"\"),\n \"record_name\",\n iff(isnotempty(event[eventTypeHuman].record_name), event[eventTypeHuman].record_name, \"\"),\n \"attribute_name\",\n iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, \"\"),\n \"attribute_value\",\n iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, \"\"),\n \"node_name\",\n iff(isnotempty(event[eventTypeHuman].node_name), event[eventTypeHuman].node_name, \"\")\n),\n dynamic(null)\n )\n// Event Specific - openssh_login & openssh_logout\n| extend SSHContext = iif(\n eventTypeHuman in (\"openssh_login\", \"openssh_logout\"),\n bag_pack(\n \"source_address_type\", \n iff(\n isnotempty(event[eventTypeHuman].source_address_type),\n case(\n event[eventTypeHuman].source_address_type == 0,\n \"Unknown\",\n event[eventTypeHuman].source_address_type == 1,\n \"IPv4\",\n event[eventTypeHuman].source_address_type == 2,\n \"IPv6\",\n event[eventTypeHuman].source_address_type == 3,\n \"UNIX Socket\",\n \"Unknown\"\n),\n \"\" \n),\n \"result_type\", \n iff(\n isnotempty(event[eventTypeHuman].result_type),\n case(\n event[eventTypeHuman].result_type == 0,\n \"Exceeded maximum attempts\",\n event[eventTypeHuman].result_type == 1,\n \"Denied by root\",\n event[eventTypeHuman].result_type == 2,\n \"Success\",\n event[eventTypeHuman].result_type == 3,\n \"No reason\",\n event[eventTypeHuman].result_type == 4,\n \"Password\",\n event[eventTypeHuman].result_type == 5,\n \"kbdint\",\n event[eventTypeHuman].result_type == 6,\n \"Public key\",\n event[eventTypeHuman].result_type == 7,\n \"Host based\",\n event[eventTypeHuman].result_type == 8,\n \"GSS API\",\n event[eventTypeHuman].result_type == 9,\n \"Invalid user\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null) \n )\n// Event Specific - performance\n// Event Specific - profile_add & profile_remove\n| extend Profile = iif(\n eventTypeHuman in (\"profile_add\", \"profile_remove\"),\n bag_pack(\n \"profile_scope\",\n iff(isnotempty(event[eventTypeHuman].profile.scope), event[eventTypeHuman].profile.scope, \"\"),\n \"profile_identifier\",\n iff(isnotempty(event[eventTypeHuman].profile.identifier), event[eventTypeHuman].profile.identifiery, \"\"),\n \"profile_uuid\",\n iff(isnotempty(event[eventTypeHuman].profile.uuid), event[eventTypeHuman].profile.uuid, \"\"),\n \"profile_display_name\",\n iff(isnotempty(event[eventTypeHuman].profile.display_name), event[eventTypeHuman].profile.display_name, \"\"),\n \"profile_organization\",\n iff(isnotempty(event[eventTypeHuman].profile.organization), event[eventTypeHuman].profile.organization, \"\"),\n \"profile_is_updated\",\n iff(isnotempty(event[eventTypeHuman].is_update), event[eventTypeHuman].is_update, \"\"),\n \"profile_install_source\", \n iff(\n isnotempty(event[eventTypeHuman].profile.install_source),\n case(\n event[eventTypeHuman].profile.install_source == 0,\n \"mdm\",\n event[eventTypeHuman].profile.install_source == 1,\n \"manual\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null)\n )\n// Event Specific - screenscharing_attach & screensharing_detach\n| extend Screensharing = iif(\n eventTypeHuman in (\"screensharing_attach\", \"screensharing_detach\"),\n bag_pack(\n \"existing_session\",\n iff(isnotempty(event[eventTypeHuman].existing_session), event[eventTypeHuman].existing_session, \"\"),\n \"graphical_session_id\",\n iff(isnotempty(event[eventTypeHuman].graphical_authentication_username), event[eventTypeHuman].graphical_authentication_username, \"\"),\n \"session_username\",\n iff(isnotempty(event[eventTypeHuman].session_username), event[eventTypeHuman].session_username, \"\"),\n \"viewer_appleid\",\n iff(isnotempty(event[eventTypeHuman].viewer_appleid), event[eventTypeHuman].viewer_appleid, \"\"),\n \"authentication_type\",\n iff(isnotempty(event[eventTypeHuman].authentication_type), event[eventTypeHuman].authentication_type, \"\"),\n \"source_address\",\n iff(isnotempty(event[eventTypeHuman].source_address), event[eventTypeHuman].source_address, \"\"),\n \"source_address_type\", \n iff(\n isnotempty(event[eventTypeHuman].source_address_type),\n case(\n event[eventTypeHuman].source_address_type == 0,\n \"Unknown\",\n event[eventTypeHuman].source_address_type == 1,\n \"IPv4\",\n event[eventTypeHuman].source_address_type == 2,\n \"IPv6\",\n event[eventTypeHuman].source_address_type == 3,\n \"UNIX Socket\",\n \"Unknown\"\n),\n \"\" \n)\n),\n dynamic(null)\n )\n// Event Specific - su\n| extend Su = iif(\n eventTypeHuman == \"su\",\n bag_pack(\n \"username\",\n iff(isnotempty(event[eventTypeHuman].username), event[eventTypeHuman].username, \"\"),\n \"uid\",\n iff(isnotempty(event[eventTypeHuman].uid), event[eventTypeHuman].uid, \"\"),\n \"args\",\n iff(isnotempty(event[eventTypeHuman].argv), event[eventTypeHuman].argv, \"\"),\n \"env_vars\",\n iff(isnotempty(event[eventTypeHuman].env), event[eventTypeHuman].env, \"\"),\n \"env_count\",\n iff(isnotempty(event[eventTypeHuman].env_count), event[eventTypeHuman].env_count, \"\"),\n \"from_username\",\n iff(isnotempty(event[eventTypeHuman].from_username), event[eventTypeHuman].from_username, \"\"),\n \"to_username\",\n iff(isnotempty(event[eventTypeHuman].to_username), event[eventTypeHuman].to_username, \"\"),\n \"failure_message\",\n iff(isnotempty(event[eventTypeHuman].failure_reason), event[eventTypeHuman].failure_reason, \"\")\n),\n dynamic(null)\n )\n// Event Specific - sudo\n| extend Sudo = iif(\n eventTypeHuman == \"sudo\",\n bag_pack(\n \"TargetProcessCommandLine\",\n iff(isnotempty(event[eventTypeHuman].command), event[eventTypeHuman].command, \"\"),\n \"attribute_name\",\n iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, \"\"),\n \"attribute_value\",\n iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, \"\")\n),\n dynamic(null)\n )\n// Event Specific - xp_malware_detected & xp_malware_remediated\n| extend Xprotect = iif(\n eventTypeHuman in (\"xp_malware_detected\", \"xp_malware_remediated\"),\n bag_pack(\n \"detected_path\",\n iff(isnotempty(event[eventTypeHuman].detected_path), event[eventTypeHuman].detected_path, \"\"),\n \"remediated_path\",\n iff(isnotempty(event[eventTypeHuman].remediated_path), event[eventTypeHuman].remediated_path, \"\"),\n \"malware_identifier\",\n iff(isnotempty(event[eventTypeHuman].malware_identifier), event[eventTypeHuman].malware_identifier, \"\"),\n \"signature_version\",\n iff(isnotempty(event[eventTypeHuman].signature_version), event[eventTypeHuman].signature_version, \"\")\n),\n dynamic(null)\n )\n| project-away\naction,\nevent,\nprocess\n};\n//\n// Jamf Protect - Network Traffic\n//\nlet JamfProtectNetworkTraffic_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Network Traffic Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Network Traffic Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventType = \"query\",\n EventSubType = \"request\",\n EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)),\n EventResult = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Prevented\", ''),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername = column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs = case(event_device_osType_s == \"MAC_OS\", \"macOS\", event_device_osType_s == \"IOS\", \"iOS\", event_device_osType_s == \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType = case(event_device_osType_s == \"MAC_OS\", \"Computer\", event_device_osType_s == \"IOS\", \"Mobile Device\", event_device_osType_s == \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery = column_ifexists('event_hostName_s', ''),\n DvcAction = case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName = column_ifexists('event_domain_s', ''),\n DstIpAddr = column_ifexists('event_destination_ips_s', ''),\n ThreatCategory = column_ifexists('event_eventType_description_s', ''),\n DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''),\n DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''),\n ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '')\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventType,\n EventSubType,\n EventStartTime,\n EventResult,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n DvcOs,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n DnsQueryTypeName,\n DvcAction,\n DnsResponseName,\n ThreatOriginalRiskLevel\n};\n// //\n// // Jamf Protect - Threat Events\n// //\nlet JamfProtectThreatEvents_view = view () {\n jamfprotect_CL\n | where event_metadata_product_s == \"Threat Events Stream\"\n // ASIM - Common Fields\n | extend EventVendor = 'Jamf'\n | extend EventProduct = 'Jamf Protect - Threat Events Stream'\n | project-rename\n | extend\n // Jamf Protect - Common Fields\n EventStartTime = column_ifexists(\"event_timestamp_t\", \"\"),\n EventResult=case(event_action_s == \"Blocked\", \"Blocked\", event_action_s == \"Detected\", \"Detected\", ''),\n EventReportUrl = column_ifexists(\"event_eventUrl_s\", \"\"),\n // Jamf Protect - Alert Details\n EventSeverity = case(event_severity_d == 2, \"Informational\", event_severity_d == 4, \"Low\", event_severity_d == 6, \"Medium\", event_severity_d == 8, \"High\", event_severity_d == 10, \"High\", \"Informational\"),\n // Jamf Protect - Source User\n SrcUsermail=column_ifexists('event_user_email_s', ''),\n SrcUsername=column_ifexists('event_user_name_s', ''),\n // Jamf Protect - Source Device Hostnames\n DvcHostname = column_ifexists(\"event_device_userDeviceName_s\", \"\"),\n DvcIpAddr = column_ifexists(\"event_source_ip_s\", \"\"),\n DvcId = column_ifexists(\"event_device_externalId_g\", \"\"),\n DvcOs=case(event_device_os_s has \"MAC_OS\", \"macOS\", event_device_os_s has \"IOS\", \"iOS\", event_device_os_s has \"ANDROID\", \"Android\", \"Other\"),\n SrcDeviceType=case(event_device_os_s has \"MAC_OS\", \"Computer\", event_device_os_s has \"IOS\", \"Mobile Device\", event_device_os_s has \"ANDROID\", \"Mobile Device\", \"Other\"),\n // Jamf Protect - DNS Specific\n DnsQuery=column_ifexists('event_hostName_s', ''),\n DvcAction=case(event_blocked_b == \"false\", \"Allowed\", event_blocked_b == \"true\", \"Blocked\", ''),\n DnsQueryName=column_ifexists('event_destination_name_s', ''),\n DstIpAddr=column_ifexists('event_destination_ip_s', ''),\n ThreatCategory=column_ifexists('event_eventType_description_s', ''),\n ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''),\n // Jamf Protect - App Specific\n TargetFileName = column_ifexists(\"event_app_name_s\", \"\"),\n TargetFileSHA1 = column_ifexists(\"event_app_sha1_s\", \"\"),\n TargetFileSHA256 = column_ifexists(\"event_app_sha256_s\", \"\")\n | project-keep\n TimeGenerated,\n EventVendor,\n EventProduct,\n EventStartTime,\n EventResult,\n EventReportUrl,\n EventSeverity,\n DvcHostname,\n DvcIpAddr,\n DvcId,\n SrcDeviceType,\n SrcUsermail,\n SrcUsername,\n DnsQuery,\n DnsQueryName,\n DstIpAddr,\n ThreatCategory,\n DvcAction,\n ThreatOriginalRiskLevel,\n TargetFileName,\n TargetFileSHA1,\n TargetFileSHA256\n};\nunion isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectTelemetryv1_view, JamfProtectTelemetryv2_view, JamfProtectNetworkTraffic_view, JamfProtectThreatEvents_view\n", "functionParameters": "", "version": 2, "tags": [ @@ -670,90 +2306,91 @@ "status": "Available", "requiredDataConnectors": [ { - "connectorId": "JamfProtect", "dataTypes": [ "jamfprotect_CL" - ] + ], + "connectorId": "JamfProtect" } ], "entityMappings": [ { - "entityType": "Host", "fieldMappings": [ { - "columnName": "DvcHostname", - "identifier": "HostName" + "identifier": "HostName", + "columnName": "DvcHostname" }, { - "columnName": "DvcOs", - "identifier": "OSFamily" + "identifier": "OSFamily", + "columnName": "DvcOs" }, { - "columnName": "DvcOsVersion", - "identifier": "OSVersion" + "identifier": "OSVersion", + "columnName": "DvcOsVersion" } - ] + ], + "entityType": "Host" }, { - "entityType": "IP", "fieldMappings": [ { - "columnName": "Host_IPs", - "identifier": "Address" + "identifier": "Address", + "columnName": "Host_IPs" } - ] + ], + "entityType": "IP" }, { - "entityType": "Account", "fieldMappings": [ { - "columnName": "TargetUsername", - "identifier": "Name" + "identifier": "Name", + "columnName": "TargetUsername" } - ] + ], + "entityType": "Account" }, { - "entityType": "Process", "fieldMappings": [ { - "columnName": "TargetProcessCurrentDirectory", - "identifier": "CommandLine" + "identifier": "CommandLine", + "columnName": "TargetProcessCurrentDirectory" }, { - "columnName": "TargetProcessId", - "identifier": "ProcessId" + "identifier": "ProcessId", + "columnName": "TargetProcessId" } - ] + ], + "entityType": "Process" }, { - "entityType": "FileHash", "fieldMappings": [ { - "columnName": "algorithm", - "identifier": "Algorithm" + "identifier": "Algorithm", + "columnName": "algorithm" }, { - "columnName": "TargetBinarySHA256", - "identifier": "Value" + "identifier": "Value", + "columnName": "TargetBinarySHA256" } - ] + ], + "entityType": "FileHash" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { - "TargetbinarySign": "TargetbinarySignerType", - "JamfPro_Status": "JamfPro", "Protect_Tags": "Tags", + "Related_Binaries": "TargetBinaryFilePath", "TargetBinarySigner": "TargetBinarySigningTeamID", - "Related_File_hash": "TargetBinarySHA256", "Protect_Analytic": "EventMessage", "Protect_Event_Type": "EventType", + "TargetbinarySign": "TargetbinarySignerType", + "Related_File_hash": "TargetBinarySHA256", "TargetBinarySignMsg": "TargetBinarySigningInfoMessage", - "Related_Binaries": "TargetBinaryFilePath" + "JamfPro_Status": "JamfPro" }, "alertDetailsOverride": { + "alertDescriptionFormat": "{{EventDescription}} - Please investigate", "alertTacticsColumnName": "Tactics", "alertSeverityColumnName": "EventSeverity", "alertDynamicProperties": [ @@ -774,16 +2411,15 @@ "alertProperty": "Techniques" } ], - "alertDisplayNameFormat": "{{EventMessage}} detected on {{DvcHostname}}", - "alertDescriptionFormat": "{{EventDescription}} - Please investigate" + "alertDisplayNameFormat": "{{EventMessage}} detected on {{DvcHostname}}" }, "incidentConfiguration": { "createIncident": true, "groupingConfiguration": { - "lookbackDuration": "PT5H", "matchingMethod": "AllEntities", - "enabled": false, - "reopenClosedIncident": false + "reopenClosedIncident": false, + "lookbackDuration": "PT5H", + "enabled": false } } } @@ -863,59 +2499,62 @@ "status": "Available", "requiredDataConnectors": [ { - "connectorId": "JamfProtect", "dataTypes": [ "jamfprotect_CL" - ] + ], + "connectorId": "JamfProtect" } ], "tactics": [ "InitialAccess" ], + "techniques": [ + "T1133" + ], "entityMappings": [ { - "entityType": "Host", "fieldMappings": [ { - "columnName": "Hostname", - "identifier": "HostName" + "identifier": "HostName", + "columnName": "Hostname" }, { - "columnName": "DvcOs", - "identifier": "OSFamily" + "identifier": "OSFamily", + "columnName": "DvcOs" } - ] + ], + "entityType": "Host" }, { - "entityType": "IP", "fieldMappings": [ { - "columnName": "DstIpAddr", - "identifier": "Address" + "identifier": "Address", + "columnName": "DstIpAddr" } - ] + ], + "entityType": "IP" }, { - "entityType": "Account", "fieldMappings": [ { - "columnName": "SrcUsermail", - "identifier": "AadUserId" + "identifier": "AadUserId", + "columnName": "SrcUsermail" }, { - "columnName": "SrcUsername", - "identifier": "FullName" + "identifier": "FullName", + "columnName": "SrcUsername" } - ] + ], + "entityType": "Account" }, { - "entityType": "URL", "fieldMappings": [ { - "columnName": "DnsQueryName", - "identifier": "Url" + "identifier": "Url", + "columnName": "DnsQueryName" } - ] + ], + "entityType": "URL" } ], "eventGroupingSettings": { @@ -925,6 +2564,7 @@ "Category": "ThreatCategory" }, "alertDetailsOverride": { + "alertDescriptionFormat": "A Network Threat has been {{EventResult}} on {{DvcHostname}}", "alertTacticsColumnName": "Tactics", "alertSeverityColumnName": "EventSeverity", "alertDynamicProperties": [ @@ -949,16 +2589,15 @@ "alertProperty": "Techniques" } ], - "alertDisplayNameFormat": "Network Threat detected on {{DvcHostname}}", - "alertDescriptionFormat": "A Network Threat has been {{EventResult}} on {{DvcHostname}}" + "alertDisplayNameFormat": "Network Threat detected on {{DvcHostname}}" }, "incidentConfiguration": { "createIncident": true, "groupingConfiguration": { - "lookbackDuration": "PT5H", "matchingMethod": "AllEntities", - "enabled": false, - "reopenClosedIncident": false + "reopenClosedIncident": false, + "lookbackDuration": "PT5H", + "enabled": false } } } @@ -1038,42 +2677,43 @@ "status": "Available", "requiredDataConnectors": [ { - "connectorId": "JamfProtect", "dataTypes": [ "jamfprotect_CL" - ] + ], + "connectorId": "JamfProtect" } ], "entityMappings": [ { - "entityType": "Host", "fieldMappings": [ { - "columnName": "DvcHostname", - "identifier": "HostName" + "identifier": "HostName", + "columnName": "DvcHostname" } - ] + ], + "entityType": "Host" }, { - "entityType": "IP", "fieldMappings": [ { - "columnName": "Host_IPs", - "identifier": "Address" + "identifier": "Address", + "columnName": "Host_IPs" } - ] + ], + "entityType": "IP" } ], "eventGroupingSettings": { "aggregationKind": "AlertPerResult" }, "customDetails": { - "Protect_Event_Type": "EventType", - "Event_Process": "TargetProcessName", "Unified_Log": "EventDescription", - "Tags": "Match_tags" + "Tags": "Match_tags", + "Protect_Event_Type": "EventType", + "Event_Process": "TargetProcessName" }, "alertDetailsOverride": { + "alertDescriptionFormat": "{{EventDescription}} has been captured in the unified logs", "alertSeverityColumnName": "EventSeverity", "alertDynamicProperties": [ { @@ -1085,16 +2725,15 @@ "alertProperty": "ProductName" } ], - "alertDisplayNameFormat": "{{EventDescription}} on {{DvcHostname}}", - "alertDescriptionFormat": "{{EventDescription}} has been captured in the unified logs" + "alertDisplayNameFormat": "{{EventDescription}} on {{DvcHostname}}" }, "incidentConfiguration": { "createIncident": true, "groupingConfiguration": { - "lookbackDuration": "PT5H", "matchingMethod": "AllEntities", - "enabled": false, - "reopenClosedIncident": false + "reopenClosedIncident": false, + "lookbackDuration": "PT5H", + "enabled": false } } } @@ -3675,7 +5314,7 @@ "contentSchemaVersion": "3.0.0", "displayName": "Jamf Protect", "publisherDisplayName": "Jamf Software, LLC", - "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

The Jamf Protect solution for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.

\n

Data Connectors: 1, Parsers: 1, Workbooks: 1, Analytic Rules: 3, Hunting Queries: 7, Playbooks: 3

\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

The Jamf Protect solution for Microsoft Sentinel enables you to ingest Jamf Protect events forwarded into Microsoft Sentinel using the Microsoft Sentinel Analytics Workspace.

\n

Data Connectors: 2, Parsers: 1, Workbooks: 1, Analytic Rules: 3, Hunting Queries: 7, Playbooks: 3

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -3705,6 +5344,11 @@ "contentId": "[variables('_dataConnectorContentId1')]", "version": "[variables('dataConnectorVersion1')]" }, + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentIdConnections2')]", + "version": "[variables('dataConnectorCCPVersion')]" + }, { "kind": "Parser", "contentId": "[variables('parserObject1').parserContentId1]", diff --git a/Solutions/Jamf Protect/Package/testParameters.json b/Solutions/Jamf Protect/Package/testParameters.json index 3f390a145a5..52529e16dab 100644 --- a/Solutions/Jamf Protect/Package/testParameters.json +++ b/Solutions/Jamf Protect/Package/testParameters.json @@ -21,6 +21,20 @@ "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" } }, + "resourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "resource group name where Microsoft Sentinel is setup" + } + }, + "subscription": { + "type": "string", + "defaultValue": "[last(split(subscription().id, '/'))]", + "metadata": { + "description": "subscription id where Microsoft Sentinel is setup" + } + }, "workbook1-name": { "type": "string", "defaultValue": "Jamf Protect Workbook", diff --git a/Solutions/Jamf Protect/Parsers/JamfProtect.yaml b/Solutions/Jamf Protect/Parsers/JamfProtect.yaml index 75d977b1529..6ed694f2026 100644 --- a/Solutions/Jamf Protect/Parsers/JamfProtect.yaml +++ b/Solutions/Jamf Protect/Parsers/JamfProtect.yaml @@ -1,816 +1,852 @@ id: d941b837-88fa-4c77-a4d8-76af0044cac0 Function: Title: Parser for JamfProtect - Version: '3.1.0' - LastUpdated: '2024-01-12' + Version: '3.2.0' + LastUpdated: '2025-01-06' Category: Microsoft Sentinel Parser FunctionName: JamfProtect FunctionAlias: JamfProtect FunctionQuery: | - let JamfProtectAlerts_view = view () { - jamfprotect_CL - | where topicType_s == "alert" - and input_eventType_s <> "GPUnifiedLogEvent" - and isnotempty(input_match_severity_d) - // JSON Parsing at earliest stage - | extend - Related_users = parse_json(input_related_users_s), - Related_files = parse_json(input_related_files_s), - Related_binaries = parse_json(input_related_binaries_s), - Related_groups = parse_json(input_related_groups_s), - Related_processes = parse_json(input_related_processes_s), - Match_facts = parse_json(input_match_facts_s), - Match_tags = parse_json(input_match_tags_s), - Match_actions = parse_json(input_match_actions_s), - Match_context = parse_json(input_match_context_s), - Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s) - // ASIM - Common Fields - | extend EventVendor = 'Jamf' - | extend EventProduct = 'Jamf Protect - Alerts' - | project-rename - EventOriginalUid = input_match_uuid_g - | extend - // Jamf Protect - Common Fields - EventType = case( - input_eventType_s == "GPClickEvent", - "Click", - input_eventType_s == "GPDownloadEvent", - "Download", - input_eventType_s == "GPFSEvent", - "FileSystem", - input_eventType_s == "GPProcessEvent", - "Process", - input_eventType_s == "GPKeylogRegisterEvent", - "Keylog", - input_eventType_s == "GPGatekeeperEvent", - "Gatekeeper", - input_eventType_s == "GPMRTEvent", - "MRT", - input_eventType_s == "GPPreventedExecutionEvent", - "ProcessDenied", - input_eventType_s == "GPThreatMatchExecEvent", - "ProcessPrevented", - input_eventType_s == "GPUnifiedLogEvent", - "UnifiedLog", - input_eventType_s == "GPUSBEvent", - "USB", - input_eventType_s == "auth-mount", - "UsbBlock", - "Unknown" - ), - EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human), - EventMessage = coalesce(Match_facts[1].name, Match_facts[0].name), - EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)), - EventResult = case(Match_actions has "Prevented", "Prevented", "Allowed"), - EventProductVersion = column_ifexists("input_host_protectVersion_s", ""), - // - // Jamf Protect - Alert details - // - EventSeverity = case(input_match_severity_d == 0, "Informational", input_match_severity_d == 1, "Low", input_match_severity_d == 2, "Medium", input_match_severity_d == 3, "High", "Informational"), - EventMatch = column_ifexists("input_match_event_matchValue_s", ""), - EventMatchType = column_ifexists("input_match_event_matchType_s", ""), - EventReportUrl = strcat("https://", context_identity_claims_hd_s, ".jamfcloud.com/Alerts/", EventOriginalUid), - // - // Jamf Protect - Source User - SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)), - // - // Jamf Protect - Source Device Hostnames - // - TargetHostname = column_ifexists("input_host_hostname_s", ""), - DvcHostname = column_ifexists("input_host_hostname_s", ""), - DvcIpAddr = column_ifexists("input_host_ips_s", ""), - DvcId = column_ifexists("input_host_provisioningUDID_g", ""), - DvcOs="macOS", - SrcDeviceType="Computer", - // - // Jamf Protect Alerts - Process - // - ProcessEventType = case(input_match_event_type_d == 0, "None", input_match_event_type_d == 1, "Create", input_match_event_type_d == 2, "Exit", ""), - ProcessEventSubType = case(input_match_event_subType_d == 7, "Exec", input_match_event_subType_d == 1, "Fork", input_match_event_subType_d == 23, "Execve", input_match_event_subType_d == 43190, "Posix Spawn", ""), - ActingProcessName = tostring(Related_processes[array_length(Related_processes) - 1].path), - ActingProcessCreationTime = format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[array_length(Related_processes) - 1].startTimestamp)), 'HH:mm:ss'), - ActingProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].responsiblePID)), - ActingProcessGuid = tostring(Related_processes[array_length(Related_processes) - 1].uuid), - ParentProcessName = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].path), ""), - ParentProcessCreationTime = iff(array_length(Related_processes) > 1, format_datetime(unixtime_milliseconds_todatetime(tolong(Related_processes[1].startTimestamp)), 'HH:mm:ss'), ""), - ParentProcessId = iff(array_length(Related_processes) > 1, toreal(Related_processes[1].pid), double(null)), - ParentProcessGuid = iff(array_length(Related_processes) > 1, tostring(Related_processes[1].uuid), ""), - TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name), - TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)), - TargetProcessGuid = tostring(Related_processes[0].uuid), - TargetProcessSHA1 = Related_binaries[0].sha1hex, - TargetProcessSHA256 = Related_binaries[0].sha256hex, - TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)), - TargetProcessCommandLine = column_ifexists("input_match_event_process_args_s", ""), - TargetProcessCurrentDirectory = column_ifexists("input_match_event_process_path_s", ""), - //TargetProcessStatusCode = column_ifexists(Related_processes[0].exitCode, ""), - TargetUserId = toreal(coalesce(Related_users[1].uid, Related_processes[0].uid)), - TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].uid)), - // - // Jamf Protect Alerts - Files - // - TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)), - TargetFileSHA1 = Related_files[0].sha1hex, - TargetFileSHA256 = Related_files[0].sha256hex, - TargetFileSize = Related_files[0].size, - TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage, - TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, "Apple", Related_files[0].signingInfo.signerType == 1, "App Store", Related_files[0].signingInfo.signerType == 2, "Developer", Related_files[0].signingInfo.signerType == 3, "Ad Hoc", Related_files[0].signingInfo.signerType == 4, "Unsigned", ""), - TargetFileSigningTeamID = Related_files[0].signingInfo.teamid, - TargetFileIsDownload = case(Related_files[0].isDownload == "true", "true", Related_files[0].isDownload == "false", "false", ""), - TargetFileIsAppBundle = case(Related_files[0].isAppBundle == "true", "true", Related_files[0].isAppBundle == "false", "false", ""), - TargetFileIsDirectory = case(Related_files[0].isDirectory == "true", "true", Related_files[0].isDirectory == "false", "false", ""), - TargetFileIsScreenshot = case(Related_files[0].isScreenShot == "true", "true", Related_files[0].isScreenShot == "false", "false", ""), - // - // Jamf Protect Alerts - Binaries - TargetBinaryFilePath = Related_binaries[0].path, - TargetBinarySHA1 = tostring(Related_binaries[0].sha1hex), - TargetBinarySHA256 = tostring(Related_binaries[0].sha256hex), - TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage, - TargetbinarySignerType = case(Related_binaries[0].signingInfo.signerType == 0, "Apple", Related_binaries[0].signingInfo.signerType == 1, "App Store", Related_binaries[0].signingInfo.signerType == 2, "Developer", Related_binaries[0].signingInfo.signerType == 3, "Ad Hoc", Related_binaries[0].signingInfo.signerType == 4, "Unsigned", ""), - TargetBinarySigningTeamID = tostring(Related_binaries[0].signingInfo.teamid), - TargetBinarySigningAppID = tostring(Related_binaries[0].signingInfo.appid) - | project-reorder - TimeGenerated, - EventStartTime, - EventVendor, - EventProduct, - EventType, - EventDescription, - EventMessage, - EventSeverity, - EventMatch, - EventMatchType, - EventResult, - EventProductVersion, - EventReportUrl, - TargetHostname, - DvcHostname, - DvcId, - DvcOs, - DvcIpAddr, - SrcDeviceType, - SrcUsername, - ProcessEventType, - ProcessEventSubType, - ActingProcessName, - ActingProcessCreationTime, - ActingProcessId, - ActingProcessGuid, - ParentProcessName, - ParentProcessCreationTime, - ParentProcessId, - ParentProcessGuid, - TargetProcessName, - TargetProcessId, - TargetProcessGuid, - TargetProcessSHA1, - TargetProcessSHA256, - TargetProcessCreationTime, - TargetProcessCommandLine, - TargetProcessCurrentDirectory, - //TargetProcessStatusCode, - TargetUsername, - TargetUserId, - TargetFilePath, - TargetFileSHA1, - TargetFileSHA256, - TargetFileSize, - TargetFileSigningInfoMessage, - TargetFileSignerType, - TargetFileSigningTeamID, - TargetFileIsAppBundle, - TargetFileIsDirectory, - TargetFileIsDownload, - TargetFileIsScreenshot, - TargetBinaryFilePath, - TargetBinarySHA1, - TargetBinarySHA256, - TargetBinarySigningInfoMessage, - TargetbinarySignerType, - TargetBinarySigningTeamID, - TargetBinarySigningAppID, - Related_users, - Related_files, - Related_binaries, - Related_groups, - Related_processes, - Match_event_process_signing, - Match_facts, - Match_actions, - Match_tags, - *input_match_event_* - | project-keep - TimeGenerated, - EventStartTime, - EventVendor, - EventProduct, - EventType, - EventDescription, - EventMessage, - EventProductVersion, - EventSeverity, - EventMatch, - EventMatchType, - EventResult, - EventReportUrl, - TargetHostname, - DvcHostname, - DvcId, - DvcOs, - DvcIpAddr, - SrcDeviceType, - SrcUsername, - ProcessEventType, - ProcessEventSubType, - ActingProcessName, - ActingProcessCreationTime, - ActingProcessId, - ActingProcessGuid, - ParentProcessName, - ParentProcessCreationTime, - ParentProcessId, - ParentProcessGuid, - TargetProcessName, - TargetProcessId, - TargetProcessGuid, - TargetProcessSHA1, - TargetProcessSHA256, - TargetProcessCreationTime, - TargetProcessCommandLine, - TargetProcessCurrentDirectory, - //TargetProcessStatusCode, - TargetUsername, - TargetUserId, - TargetFilePath, - TargetFileSHA1, - TargetFileSHA256, - TargetFileSize, - TargetFileSigningInfoMessage, - TargetFileSignerType, - TargetFileSigningTeamID, - TargetFileIsAppBundle, - TargetFileIsDirectory, - TargetFileIsDownload, - TargetFileIsScreenshot, - TargetBinaryFilePath, - TargetBinarySHA1, - TargetBinarySHA256, - TargetBinarySigningInfoMessage, - TargetbinarySignerType, - TargetBinarySigningTeamID, - TargetBinarySigningAppID, - Related_users, - Related_files, - Related_binaries, - Related_groups, - Related_processes, - Match_event_process_signing, - Match_facts, - Match_actions, - Match_tags, - *input_match_event_* - }; - // - // Jamf Protect - Unified Logs - // - let JamfProtectUnifiedLog_view = view () { - jamfprotect_CL - | where input_eventType_s == "GPUnifiedLogEvent" - and isnotempty(input_match_severity_d) - // JSON Parsing at earliest stage - | extend - Related_users = parse_json(input_related_users_s), - Related_files = parse_json(input_related_files_s), - Related_binaries = parse_json(input_related_binaries_s), - Related_groups = parse_json(input_related_groups_s), - Related_processes = parse_json(input_related_processes_s), - Match_facts = parse_json(input_match_facts_s), - Match_tags = parse_json(input_match_tags_s), - Match_actions = parse_json(input_match_actions_s), - Match_context = parse_json(input_match_context_s), - Match_event_process_signing = parse_json(input_match_event_process_signingInfo_s) - // ASIM - Common Fields - | extend EventVendor = 'Jamf' - | extend EventProduct = 'Jamf Protect - Unified Log' - | project-rename - EventOriginalUid = input_match_uuid_g - | extend - // Jamf Protect - Common Fields - EventType = case( - input_eventType_s == "GPClickEvent", - "Click", - input_eventType_s == "GPDownloadEvent", - "Download", - input_eventType_s == "GPFSEvent", - "FileSystem", - input_eventType_s == "GPProcessEvent", - "Process", - input_eventType_s == "GPKeylogRegisterEvent", - "Keylog", - input_eventType_s == "GPGatekeeperEvent", - "Gatekeeper", - input_eventType_s == "GPMRTEvent", - "MRT", - input_eventType_s == "GPPreventedExecutionEvent", - "ProcessDenied", - input_eventType_s == "GPThreatMatchExecEvent", - "ProcessPrevented", - input_eventType_s == "GPUnifiedLogEvent", - "UnifiedLog", - input_eventType_s == "GPUSBEvent", - "USB", - input_eventType_s == "Auth-mount", - "UsbBlock", - "Unknown" - ), - EventDescription = coalesce(Match_facts[1].human, Match_facts[0].human), - EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)), - EventResult = case(Match_actions has "Prevented", "Prevented", "Allowed"), - // - // Jamf Protect - Unified Logs details - // - EventSeverity = case(input_match_severity_d == 0, "Informational", input_match_severity_d == 1, "Low", input_match_severity_d == 2, "Medium", input_match_severity_d == 3, "High", "Informational"), - EventMatch = column_ifexists("input_match_event_matchValue_s", ""), - EventMatchType = column_ifexists("input_match_event_matchType_s", ""), - EventReportUrl = strcat("https://", context_identity_claims_hd_s, ".jamfcloud.com/Alerts/", EventOriginalUid), - // - // Jamf Protect - Source User - SrcUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)), - // - // Jamf Protect - Source Device Hostnames - // - TargetHostname = column_ifexists("input_host_hostname_s", ""), - DvcHostname = column_ifexists("input_host_hostname_s", ""), - DvcIpAddr = column_ifexists("input_host_ips_s", ""), - DvcId = column_ifexists("input_host_provisioningUDID_g", ""), - DvcOs="macOS", - SrcDeviceType="Computer", - // - // Jamf Protect Unified Logs - Process - // - //ParentProcessName = coalesce(input_match_event_process_ppid_d, parse_json('input_related_processes_s')[0].ppid), //column_ifexists("exec_chain_child_parent_path_s", ""), coalesce('input.match.event.process.ppid', mvindex('input.related.processes{}.ppid', 0)) - ProcessEventType = case(input_match_event_type_d == 0, "None", input_match_event_type_d == 1, "Create", input_match_event_type_d == 2, "Exit", ""), - ProcessEventSubType = case(input_match_event_subType_d == 7, "Exec", input_match_event_subType_d == 1, "Fork", input_match_event_subType_d == 23, "Execve", input_match_event_subType_d == 43190, "Posix Spawn", ""), - ParentProcessId = coalesce(input_match_event_process_ppid_d, toreal(Related_processes[0].ppid)), - ParentProcessGuid = tostring(coalesce(input_match_event_process_pgid_d, toreal(Related_processes[0].pgid))), - TargetProcessName = coalesce(input_match_event_process_name_s, Related_processes[0].name), - TargetProcessId = coalesce(toreal(input_match_event_process_pid_d), toreal(Related_processes[0].pid)), - TargetProcessGuid = tostring(Related_processes[0].uuid), - TargetProcessSHA1 = Related_binaries[0].sha1hex, - TargetProcessCreationTime = unixtime_milliseconds_todatetime(tolong(input_match_event_process_startTimestamp_d)), - TargetProcessCommandLine = column_ifexists("input_match_event_process_args_s", ""), - TargetProcessCurrentDirectory = column_ifexists("input_match_event_process_path_s", ""), - TargetUserId = toreal(coalesce(Related_users[1].uid, Related_users[0].uid)), - TargetUsername = tostring(coalesce(Related_users[1].name, Related_users[0].name)), - // - // Jamf Protect Unified Logs - Files - // - TargetFilePath = tostring(coalesce(input_match_event_path_s, Related_files[0].path)), - TargetFileSHA1 = Related_files[0].sha1hex, - TargetFileSHA256 = Related_files[0].sha256hex, - TargetFileSize = Related_files[0].size, - TargetFileSigningInfoMessage = Related_files[0].signingInfo.statusMessage, - TargetFileSignerType = case(Related_files[0].signingInfo.signerType == 0, "Apple", Related_files[0].signingInfo.signerType == 1, "App Store", Related_files[0].signingInfo.signerType == 2, "Developer", Related_files[0].signingInfo.signerType == 3, "Ad Hoc", Related_files[0].signingInfo.signerType == 4, "Unsigned", ""), - TargetFileSigningTeamID = Related_files[0].signingInfo.teamid, - TargetFileIsDownload = case(Related_files[0].isDownload == "true", "true", Related_files[0].isDownload == "false", "false", ""), - TargetFileIsAppBundle = case(Related_files[0].isAppBundle == "true", "true", Related_files[0].isAppBundle == "false", "false", ""), - TargetFileIsDirectory = case(Related_files[0].isDirectory == "true", "true", Related_files[0].isDirectory == "false", "false", ""), - TargetFileIsScreenshot = case(Related_files[0].isScreenShot == "true", "true", Related_files[0].isScreenShot == "false", "false", "") - | project-reorder - TimeGenerated, - EventStartTime, - EventVendor, - EventProduct, - EventType, - EventDescription, - EventSeverity, - EventMatch, - EventMatchType, - EventResult, - EventReportUrl, - TargetHostname, - DvcHostname, - DvcId, - DvcOs, - DvcIpAddr, - SrcDeviceType, - SrcUsername, - ProcessEventType, - ProcessEventSubType, - ParentProcessId, - ParentProcessGuid, - TargetProcessName, - TargetProcessId, - TargetProcessGuid, - TargetProcessSHA1, - TargetProcessCreationTime, - TargetProcessCommandLine, - TargetProcessCurrentDirectory, - TargetUsername, - TargetUserId, - TargetFilePath, - TargetFileSHA1, - TargetFileSHA256, - TargetFileSize, - TargetFileSigningInfoMessage, - TargetFileSignerType, - TargetFileSigningTeamID, - TargetFileIsAppBundle, - TargetFileIsDirectory, - TargetFileIsDownload, - TargetFileIsScreenshot, - Related_users, - Related_files, - Related_binaries, - Related_groups, - Related_processes, - Match_event_process_signing, - Match_facts, - Match_actions, - Match_tags - | project-keep - TimeGenerated, - EventStartTime, - EventVendor, - EventProduct, - EventType, - EventDescription, - EventSeverity, - EventMatch, - EventMatchType, - EventResult, - EventReportUrl, - TargetHostname, - DvcHostname, - DvcId, - DvcOs, - DvcIpAddr, - SrcDeviceType, - SrcUsername, - ProcessEventType, - ProcessEventSubType, - ParentProcessId, - ParentProcessGuid, - TargetProcessName, - TargetProcessId, - TargetProcessGuid, - TargetProcessSHA1, - TargetProcessCreationTime, - TargetProcessCommandLine, - TargetProcessCurrentDirectory, - TargetUsername, - TargetUserId, - TargetFilePath, - TargetFileSHA1, - TargetFileSHA256, - TargetFileSize, - TargetFileSigningInfoMessage, - TargetFileSignerType, - TargetFileSigningTeamID, - TargetFileIsAppBundle, - TargetFileIsDirectory, - TargetFileIsDownload, - TargetFileIsScreenshot, - Related_users, - Related_files, - Related_binaries, - Related_groups, - Related_processes, - Match_event_process_signing, - Match_facts, - Match_actions, - Match_tags, - *input_match_event* - }; - // - // Jamf Protect - Network Traffic - // - let JamfProtectNetworkTraffic_view = view () { - jamfprotect_CL - | where event_metadata_product_s == "Network Traffic Stream" - // ASIM - Common Fields - | extend EventVendor = 'Jamf' - | extend EventProduct = 'Jamf Protect - Network Traffic Stream' - | project-rename - | extend - // Jamf Protect - Common Fields - EventType = "query", - EventSubType = "request", - EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)), - EventResult = case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Prevented", ''), - // Jamf Protect - Source User - SrcUsermail=column_ifexists('event_user_email_s', ''), - SrcUsername = column_ifexists('event_user_name_s', ''), - // Jamf Protect - Source Device Hostnames - DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s), - DvcIpAddr = column_ifexists("event_source_ip_s", ""), - DvcId = column_ifexists("event_device_externalId_g", ""), - DvcOs = case(event_device_osType_s == "MAC_OS", "macOS", event_device_osType_s == "IOS", "iOS", event_device_osType_s == "ANDROID", "Android", "Other"), - SrcDeviceType = case(event_device_osType_s == "MAC_OS", "Computer", event_device_osType_s == "IOS", "Mobile Device", event_device_osType_s == "ANDROID", "Mobile Device", "Other"), - // Jamf Protect - DNS Specific - DnsQuery = column_ifexists('event_hostName_s', ''), - DvcAction = case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Blocked", ''), - DnsQueryName = column_ifexists('event_domain_s', ''), - DstIpAddr = column_ifexists('event_destination_ips_s', ''), - ThreatCategory = column_ifexists('event_eventType_description_s', ''), - DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''), - DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''), - ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '') - | project-keep - TimeGenerated, - EventVendor, - EventProduct, - EventType, - EventSubType, - EventStartTime, - EventResult, - DvcHostname, - DvcIpAddr, - DvcId, - DvcOs, - SrcDeviceType, - SrcUsermail, - SrcUsername, - DnsQuery, - DnsQueryName, - DstIpAddr, - DnsQueryTypeName, - DvcAction, - DnsResponseName, - ThreatOriginalRiskLevel - }; - // - // Jamf Protect - Endpoint Telemetry - // - let JamfProtectTelemetry_view = view () { - jamfprotect_CL - | where header_event_name_s startswith "AUE_" - or header_event_name_s == "PLAINTEXT_LOG_COLLECTION_EVENT" - or header_event_name_s == "SYSTEM_PERFORMANCE_METRICS" - // ASIM - Common Fields - | extend EventVendor = 'Jamf' - | extend EventProduct = 'Jamf Protect - Telemetry' - // Data Field Normalization - //| project-rename - // DvcIpAddr = input_host_ips_s, - // DvcId = context_identity_claims_clientid_g - | extend - // Jamf Protect Alerts - Generic Information - EventSeverity = case( - input_match_severity_d == 0, - "Informational", - input_match_severity_d == 1, - "Low", - input_match_severity_d == 2, - "Medium", - input_match_severity_d == 3, - "High", - "Informational" - ), - EventStartTime = unixtime_milliseconds_todatetime(tolong(timestamp_d)), - EventResult = coalesce(return_description_s, texts_s), - // Jamf Protect Telemetry - Endpoint Information - TargetModel = column_ifexists("metrics_hw_model_s", ""), - DvcOsVersion = column_ifexists("host_info_osversion_s", ""), - TargetHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s), - DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s), - DvcIpAddr = column_ifexists("input_host_ips_s", ""), - DvcId = column_ifexists("context_identity_claims_clientid_g", ""), - // Jamf Protect - Event Types - EventType = case( - header_event_name_s == "AUE_add_to_group", - "UserAddedToGroup", - header_event_name_s == "AUE_AUDITCTL", - "AuditEvent", - header_event_name_s == "AUE_AUDITON_SPOLICY", - "AuditEvent", - header_event_name_s == "AUE_auth_user", - "Elevate", - header_event_name_s == "AUE_BIND", - "EndpointNetworkSession", - header_event_name_s == "AUE_BIOS_FIRMWARE_VERSIONS", - "SystemInformation", - header_event_name_s == "AUE_CHDIR", - "FolderMoved", - header_event_name_s == "AUE_CHROOT", - "FolderModified", - header_event_name_s == "AUE_CONNECT", - "EndpointNetworkSession", - header_event_name_s == "AUE_create_group", - "GroupCreated", - header_event_name_s == "AUE_create_user", - "UserCreated", - header_event_name_s == "AUE_delete_group", - "GroupDeleted", - header_event_name_s == "AUE_delete_user", - "UserDeleted", - header_event_name_s == "AUE_EXECVE", - "ProcessCreated", - header_event_name_s == "AUE_EXIT", - "ProcessTerminated", - header_event_name_s == "AUE_FORK", - "ProcessCreated", - header_event_name_s == "AUE_GETAUID", - "", - header_event_name_s == "AUE_KILL", - "ProcessTerminated", - header_event_name_s == "AUE_LISTEN", - "EndpointNetworkSession", - header_event_name_s == "AUE_logout", - "Logoff", - header_event_name_s == "AUE_lw_login", - "Logon", - header_event_name_s == "AUE_MAC_SET_PROC", - "AuditEvent", - header_event_name_s == "AUE_modify_group", - "GroupModified", - header_event_name_s == "AUE_modify_password", - "PasswordChanged", - header_event_name_s == "AUE_modify_user", - "UserModified", - header_event_name_s == "AUE_MOUNT", - "VolumeMount", - header_event_name_s == "AUE_openssh", - "SshInitiated", - header_event_name_s == "AUE_PIDFORTASK", - "ProcessCreated", - header_event_name_s == "AUE_POSIX_SPAWN", - "ProcessCreated", - header_event_name_s == "AUE_remove_from_group", - "UserRemovedFromGroup", - header_event_name_s == "AUE_SESSION_CLOSE", - "Logoff", - header_event_name_s == "AUE_SESSION_END", - "Logoff", - header_event_name_s == "AUE_SESSION_START", - "Logon", - header_event_name_s == "AUE_SESSION_UPDATE", - "", - header_event_name_s == "AUE_SETPRIORITY", - "", - header_event_name_s == "AUE_SETSOCKOPT", - "", - header_event_name_s == "AUE_SETTIMEOFDAY", - "SystemChange", - header_event_name_s == "AUE_shutdown", - "ShutdownInitiated", - header_event_name_s == "AUE_SOCKETPAIR", - "", - header_event_name_s == "AUE_ssauthint", - "Elevate", - header_event_name_s == "AUE_ssauthmech", - "Elevate", - header_event_name_s == "AUE_ssauthorize", - "Elevate", - header_event_name_s == "AUE_TASKFORPID", - "", - header_event_name_s == "AUE_TASKNAMEFORPID", - "", - header_event_name_s == "AUE_UNMOUNT", - "VolumeUnmount", - header_event_name_s == "AUE_WAIT4", - "ProcessTerminated", - header_event_name_s == "PLAINTEXT_LOG_COLLECTION_EVENT", - "LogFileCollected", - header_event_name_s == "SYSTEM_PERFORMANCE_METRICS", - "SystemPerformanceMetrics", - "Unknown" - ), - // Jamf Protect Telemetry - Process - ParentProcessName = column_ifexists("subject_responsible_process_name_s", ""), - ParentProcessId = column_ifexists("subject_responsible_process_id_d", ""), - ParentProcessGuid = column_ifexists("exec_chain_child_parent_uuid_g", ""), - TargetProcessName = column_ifexists("subject_process_name_s", ""), - TargetProcessId = column_ifexists("subject_process_id_d", ""), - TargetProcessGuid = column_ifexists("exec_chain_thread_uuid_g", ""), - TargetProcessSHA256 = todynamic(column_ifexists("subject_process_hash_s", "")), - TargetUserId = toreal(column_ifexists("subject_user_id_d", "")), - TargetUsername = tostring(column_ifexists("subject_user_name_s", "")), - TargetProcessCommandLine = column_ifexists("exec_args_args_compiled_s", ""), - ActorUsername = tostring(column_ifexists("subject_effective_user_name_s", "")), - ActorUserId = column_ifexists("subject_audit_user_name_s", ""), - //column_ifexists("application_name_s", ""), - // - // Jamf Protect Telemetry - Audit/Group - // - GroupName = todynamic(column_ifexists("subject_group_name_s", "")), - // Jamf Protect Telemetry - Network - DstIpAddr = column_ifexists("socket_inet_ip_address_s", ""), - DstPortNumber = column_ifexists("socket_inet_port_d", ""), - NetworkProtocolVersion = case(socket_inet_id_d == 128, "IPV4", socket_inet_id_d == 129, "IPV6", ""), - SrcIpAddr = column_ifexists("subject_terminal_id_ip_address_s", ""), - // - // Jamf Protect Telemetry - Binaries - // - // TargetBinaryFilePath = todynamic(Related_binaries[0].path), - TargetBinarySHA256 = tostring(identity_cd_hash_s), - // TargetBinarySigningInfoMessage = Related_binaries[0].signingInfo.statusMessage, - TargetbinarySignerType = case(identity_signer_type_d == 0, "Developer", identity_signer_type_d == 1, "Apple", ""), - TargetBinarySigningTeamID = tostring(identity_team_id_s), - TargetBinarySigningAppID = tostring(identity_signer_id_s), - // - // Jamf Protect Telemetry - Log File Collection - // - TargetFilePath = tostring(parse_json(path_s)) - | project-reorder - EventStartTime, - EventVendor, - EventProduct, - EventType, - EventSeverity, - EventResult, - TargetHostname, - DvcHostname, - DvcId, - DvcOsVersion, - DvcIpAddr, - TargetModel, - TargetUserId, - TargetUsername, - ParentProcessName, - ParentProcessId, - ParentProcessGuid, - TargetProcessName, - TargetProcessId, - TargetProcessGuid, - TargetProcessSHA256, - TargetProcessCommandLine, - ActorUsername, - ActorUserId, - TargetBinarySHA256, - TargetbinarySignerType, - TargetBinarySigningTeamID, - TargetBinarySigningAppID, - GroupName, - SrcIpAddr, - DstIpAddr, - DstPortNumber, - NetworkProtocolVersion, - TargetFilePath - | project-away - arguments_sflags_d, - arguments_am_failure_d, - arguments_am_success_d - }; - // - // Jamf Protect - Threat Events - // - let JamfProtectThreatEvents_view = view () { - jamfprotect_CL - | where event_metadata_product_s == "Threat Events Stream" - // ASIM - Common Fields - | extend EventVendor = 'Jamf' - | extend EventProduct = 'Jamf Protect - Threat Events Stream' - | project-rename - | extend - // Jamf Protect - Common Fields - EventStartTime = column_ifexists("event_timestamp_t", ""), - EventResult=case(event_action_s == "Blocked", "Blocked", event_action_s == "Detected", "Detected", ''), - EventReportUrl = column_ifexists("event_eventUrl_s", ""), - // Jamf Protect - Alert Details - EventSeverity = case(event_severity_d == 2, "Informational", event_severity_d == 4, "Low", event_severity_d == 6, "Medium", event_severity_d == 8, "High", event_severity_d == 10, "High", "Informational"), - // Jamf Protect - Source User - SrcUsermail=column_ifexists('event_user_email_s', ''), - SrcUsername=column_ifexists('event_user_name_s', ''), - // Jamf Protect - Source Device Hostnames - DvcHostname = column_ifexists("event_device_userDeviceName_s", ""), - DvcIpAddr = column_ifexists("event_source_ip_s", ""), - DvcId = column_ifexists("event_device_externalId_g", ""), - DvcOs=case(event_device_os_s has "MAC_OS", "macOS", event_device_os_s has "IOS", "iOS", event_device_os_s has "ANDROID", "Android", "Other"), - SrcDeviceType=case(event_device_os_s has "MAC_OS", "Computer", event_device_os_s has "IOS", "Mobile Device", event_device_os_s has "ANDROID", "Mobile Device", "Other"), - // Jamf Protect - DNS Specific - DnsQuery=column_ifexists('event_hostName_s', ''), - DvcAction=case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Blocked", ''), - DnsQueryName=column_ifexists('event_destination_name_s', ''), - DstIpAddr=column_ifexists('event_destination_ip_s', ''), - ThreatCategory=column_ifexists('event_eventType_description_s', ''), - ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''), - // Jamf Protect - App Specific - TargetFileName = column_ifexists("event_app_name_s", ""), - TargetFileSHA1 = column_ifexists("event_app_sha1_s", ""), - TargetFileSHA256 = column_ifexists("event_app_sha256_s", "") - | project-keep - TimeGenerated, - EventVendor, - EventProduct, - EventStartTime, - EventResult, - EventReportUrl, - EventSeverity, - DvcHostname, - DvcIpAddr, - DvcId, - SrcDeviceType, - SrcUsermail, - SrcUsername, - DnsQuery, - DnsQueryName, - DstIpAddr, - ThreatCategory, - DvcAction, - ThreatOriginalRiskLevel, - TargetFileName, - TargetFileSHA1, - TargetFileSHA256 - }; - union isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectNetworkTraffic_view, JamfProtectTelemetry_view, JamfProtectThreatEvents_view + let JamfProtectAlerts_view = view () { + jamfprotectalerts_CL + | extend + ActingProcessCreationTime = unixtime_seconds_todatetime(tolong(input.related.processes[array_length(input.related.processes) - 1].startTimestamp)), + ParentProcessCreationTime = iff( + array_length(input.related.processes) > 1, + unixtime_seconds_todatetime(tolong(input.related.processes[0].startTimestamp)), + datetime(null) + ), + TargetProcessCreationTime = unixtime_seconds_todatetime(todouble(input.related.processes[0].startTimestamp)), + TargetUserId = coalesce(input.related.users[1].uid, input.related.users[0].uid), + TargetUsername = coalesce(input.related.users[1].name, input.related.users[0].name) + }; + let JamfProtectUnifiedLog_view = view () { + jamfprotectunifiedlogs_CL + | extend EventStartTime = unixtime_seconds_todatetime(tolong(input.match.event.timestamp)) + }; + // + // Jamf Protect - Endpoint Telemetry + // + let JamfProtectTelemetryv1_view = view () { + jamfprotecttelemetryv1_CL + | extend + EventStartTime = unixtime_seconds_todatetime(todouble(header.time_seconds_epoch)), + EventResult = coalesce(return.description, texts) + }; + let JamfProtectTelemetryv2_view = view () { + jamfprotecttelemetryv2_CL + // Generic Fields + | extend + EventExpanded = tostring(parse_json(event)[strcat_array(bag_keys(event), '.')]), + eventTypeHuman = tostring(bag_keys(event)[0]) + | extend EventResult = iif((event[eventTypeHuman]['success'] == true), "Success", dynamic(null)) + | extend + EventMessage = case( + eventTypeHuman == "authentication", + "A user authentication happened", + eventTypeHuman == "authorization_judgement", + "A process has its rights petition judged", + eventTypeHuman == "authorization_petition", + "A process has its rights petition judged", + eventTypeHuman == "bios_uefi", + "Collection of bios and firmware data", + eventTypeHuman == "btm_launch_item_add", + "Apple’s Background Task Manager notified that an item has been added", + eventTypeHuman == "btm_launch_item_remove", + "Apple’s Background Task Manager notified that an existing item has been removed", + eventTypeHuman == "chroot", + "Software has changed its apparent root directory in which it's actively operating out of", + eventTypeHuman == "cs_invalidated", + "The system detected that a process has had its code signature marked as invalid", + eventTypeHuman == "exec", + "A new process has been executed", + eventTypeHuman == "kextload", + "A kernel extension (kext) was loaded", + eventTypeHuman == "kextunload", + "A kernel extension (kext) was unloaded", + eventTypeHuman == "login_login", + "A user attempted to log in using /usr/bin/login", + eventTypeHuman == "login_logout", + "A user logged out from /usr/bin/login", + eventTypeHuman == "lw_session_lock", + "A user has locked the screen", + eventTypeHuman == "lw_session_login", + "A user has logged in via the Login Window", + eventTypeHuman == "lw_session_logout", + "A user has logged out of an active graphical session", + eventTypeHuman == "lw_session_unlock", + "A user has unlocked the screen from the Login Window", + eventTypeHuman == "mount", + "A file system has been mounted", + eventTypeHuman == "od_attribute_set", + "Attribute set on user or group using Open Directory", + eventTypeHuman == "od_attribute_value_add", + "Attribute added to a user or group using Open Directory", + eventTypeHuman == "od_attribute_value_remove", + "Attribute removed from a user or group using Open Directory", + eventTypeHuman == "od_create_group", + "A group has been created using Open Directory", + eventTypeHuman == "od_create_user", + "A user has been created using Open Directory", + eventTypeHuman == "od_delete_group", + "A group has been deleted using Open Directory", + eventTypeHuman == "od_delete_user", + "A user has been deleted using Open Directory", + eventTypeHuman == "od_disable_user", + "A user has been disabled using Open Directory", + eventTypeHuman == "od_enable_user", + "A user has been enabled using Open Directory", + eventTypeHuman == "od_group_add", + "A member has been added to a group using Open Directory", + eventTypeHuman == "od_group_remove", + "A member has been removed from a group using Open Directory", + eventTypeHuman == "od_group_set", + "A group has a member initialised or replaced using Open Directory", + eventTypeHuman == "od_modify_password", + "A user password is modified via Open Directory", + eventTypeHuman == "openssh_login", + "A user has logged into the system via OpenSSH", + eventTypeHuman == "openssh_logout", + "A user has logged out of an OpenSSH session", + eventTypeHuman == "performance", + "Collection of system performance data", + eventTypeHuman == "profile_add", + "A configuration profile is installed on the system", + eventTypeHuman == "profile_remove", + "A configuration profile is removed from the system", + eventTypeHuman == "remount", + "A file system has been mounted", + eventTypeHuman == "screenscharing_attach", + "A screensharing session has attached to a graphical session", + eventTypeHuman == "screenscharing_detach", + "A screensharing session has detached from a graphical session", + eventTypeHuman == "settime", + "The system time was attempted to be set", + eventTypeHuman == "su", + "A user attempts to start a new shell using a substitute user identity", + eventTypeHuman == "sudo", + "A sudo attempt occured", + eventTypeHuman == "unmount", + "A file system has been mounted", + eventTypeHuman == "xp_malware_detected", + "Apple’s XProtect detected malware on the system", + eventTypeHuman == "xp_malware_remediated", + "Apple’s XProtect remediated malware on the system", + eventTypeHuman == "file_collection", + "A crash or diagnostic file has been collected", + eventTypeHuman == "log_collection", + "Entries from a log file have been collected", + "No reason yet defined for this event" + ), + EventType = case( + eventTypeHuman == "authentication", + "Logon", + eventTypeHuman == "authorization_judgement", + "ProcessCreated", + eventTypeHuman == "authorization_petition", + "ProcessCreated", + eventTypeHuman == "bios_uefi", + "Hardware", + eventTypeHuman == "btm_launch_item_add", + "Create", + eventTypeHuman == "btm_launch_item_remove", + "Delete", + eventTypeHuman == "chroot", + "Set", + eventTypeHuman == "cs_invalidated", + "Other", + eventTypeHuman == "exec", + "ProcessCreated", + eventTypeHuman == "kextload", + "Create", + eventTypeHuman == "kextunload", + "Delete", + eventTypeHuman == "login_login", + "Logon", + eventTypeHuman == "login_logout", + "Logoff", + eventTypeHuman == "lw_session_lock", + "Logoff", + eventTypeHuman == "lw_session_login", + "Logon", + eventTypeHuman == "lw_session_logout", + "Logoff", + eventTypeHuman == "lw_session_unlock", + "Logon", + eventTypeHuman == "mount", + "FileSystemMounted", + eventTypeHuman == "od_attribute_set", + "Set", + eventTypeHuman == "od_attribute_value_add", + "Create", + eventTypeHuman == "od_attribute_value_remove", + "Delete", + eventTypeHuman == "od_create_group", + "GroupCreated", + eventTypeHuman == "od_create_user", + "UserCreated", + eventTypeHuman == "od_delete_group", + "GroupDeleted", + eventTypeHuman == "od_delete_user", + "UserDeleted", + eventTypeHuman == "od_disable_user", + "UserDisabled", + eventTypeHuman == "od_enable_user", + "UserEnabled", + eventTypeHuman == "od_group_add", + "UserAddedToGroup", + eventTypeHuman == "od_group_remove", + "UserRemovedFromGroup", + eventTypeHuman == "od_group_set", + "GroupModified", + eventTypeHuman == "od_modify_password", + "PasswordChanged", + eventTypeHuman == "openssh_login", + "Logon", + eventTypeHuman == "openssh_logout", + "Logoff", + eventTypeHuman == "performance", + "PerformanceData", + eventTypeHuman == "profile_add", + "Create", + eventTypeHuman == "profile_remove", + "Delete", + eventTypeHuman == "remount", + "FileSystemRemounted", + eventTypeHuman == "screenscharing_attach", + "Logon", + eventTypeHuman == "screenscharing_detach", + "Logoff", + eventTypeHuman == "settime", + "Set", + eventTypeHuman == "su", + "Elevate", + eventTypeHuman == "sudo", + "Elevate", + eventTypeHuman == "unmount", + "FileSystemUnmounted", + eventTypeHuman == "xp_malware_detected", + "MalwareDetected", + eventTypeHuman == "xp_malware_remediated", + "MalwareRemediated", + "" + ), + EventSubType = case( + eventTypeHuman == "authentication", + "Interactive", + eventTypeHuman == "btm_launch_item_add", + "btm", + eventTypeHuman == "btm_launch_item_remove", + "btm", + eventTypeHuman == "chroot", + "Directory", + eventTypeHuman == "cs_invalidated", + "Other", + eventTypeHuman == "kextload", + "System Settings", + eventTypeHuman == "kextunload", + "System Settings", + eventTypeHuman == "login_login", + "Interactive", + eventTypeHuman == "login_logout", + "Interactive", + eventTypeHuman == "lw_session_lock", + "Interactive", + eventTypeHuman == "lw_session_login", + "Interactive", + eventTypeHuman == "lw_session_logout", + "Interactive", + eventTypeHuman == "lw_session_unlock", + "Interactive", + eventTypeHuman == "od_attribute_set", + "Attribute", + eventTypeHuman == "od_attribute_value_add", + "Attribute", + eventTypeHuman == "od_attribute_value_remove", + "Attribute", + eventTypeHuman == "openssh_login", + "Interactive", + eventTypeHuman == "openssh_logout", + "Interactive", + eventTypeHuman == "profile_add", + "Configuration Profile", + eventTypeHuman == "profile_remove", + "Configuration Profile", + eventTypeHuman == "screenscharing_attach", + "RemoteInteractive", + eventTypeHuman == "screenscharing_detach", + "RemoteInteractive", + eventTypeHuman == "settime", + "System Settings", + eventTypeHuman == "su", + "Interactive", + eventTypeHuman == "sudo", + "Interactive", + "" + ) + // Jamf Protect Telemetry - Event Process + | extend eventContext = + iif( + isnotempty(event[eventTypeHuman]['app']['audit_token']), + event[eventTypeHuman]['app'], + iif( + isnotempty(event[eventTypeHuman]['target']['audit_token']), + event[eventTypeHuman]['target'], + iif( + isnotempty(event[eventTypeHuman]['data']['od']['audit_token']), + event[eventTypeHuman]['data']['od'], + iif( + isnotempty(event[eventTypeHuman]['data']['token']['audit_token']), + event[eventTypeHuman]['data']['token'], + iif( + isnotempty(event[eventTypeHuman]['data']['touchid']['audit_token']), + event[eventTypeHuman]['data']['touchid'], + iif( + isnotempty(event[eventTypeHuman]['instigator']['audit_token']), + event[eventTypeHuman]['instigator'], + ['process'] + ) + ) + ) + ) + ) + ) + | extend + TargetProcessName = tostring(eventContext.executable.path), + TargetProcessId = tostring(eventContext.audit_token.pid), + TargetProcessGuid = tostring(eventContext.audit_token.uuid), + TargetProcessCreationTime = tostring(eventContext.start_time), + TargetProcessSHA1 = tostring(eventContext.executable.sha1), + TargetProcessSHA256 = tostring(eventContext.executable.sha256), + TargetProcessCommandLine = event[eventTypeHuman]['args'], + TargetProcessTTY = tostring(eventContext.tty.path), + TargetBinarySigningAppID = tostring(eventContext.signing_id), + TargetBinarySigningTeamID = tostring(eventContext.team_id), + TargetBinaryCDHash = tostring(eventContext.cdhash), + TargetBinaryIsESClient = tobool(eventContext.is_es_client), + TargetBinaryIsPlatformBinary = tobool(eventContext.is_platform_binary), + TargetUserId = tostring(eventContext.audit_token.euid), + ActingProcessId = tostring(eventContext.parent_audit_token.pid), + ActingProcessGuid = tostring(eventContext.parent_audit_token.uuid), + ActorUserId = tostring(eventContext.parent_audit_token.euid), + ParentProcessId = tostring(eventContext.responsible_audit_token.pid), + ParentProcessGuid = tostring(eventContext.responsible_audit_token.uuid) + // Jamf Protect Telemetry - Revealing Code Signing flags + | extend TargetProcessCodesignFlags = + iif(isnotempty(eventContext.codesigning_flags), + bag_pack( + "CS_VALID", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000001) > 0, true, false), + "CS_ADHOC", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000002) > 0, true, false), + "CS_GET_TASK_ALLOW", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000004) > 0, true, false), + "CS_INSTALLER", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000008) > 0, true, false), + "CS_FORCED_LV", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000010) > 0, true, false), + "CS_INVALID_ALLOWED", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000020) > 0, true, false), + "CS_HARD", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000100) > 0, true, false), + "CS_KILL", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000200) > 0, true, false), + "CS_CHECK_EXPIRATION", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000400) > 0, true, false), + "CS_RESTRICT", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00000800) > 0, true, false), + "CS_ENFORCEMENT", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00001000) > 0, true, false), + "CS_REQUIRE_LV", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00002000) > 0, true, false), + "CS_ENTITLEMENTS_VALIDATED", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00004000) > 0, true, false), + "CS_NVRAM_UNRESTRICTED", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00008000) > 0, true, false), + "CS_RUNTIME", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00010000) > 0, true, false), + "CS_LINKER_SIGNED", + iff(binary_and(toint(eventContext.codesigning_flags), 0x20000) > 0, true, false), + "CS_EXEC_SET_HARD", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00100000) > 0, true, false), + "CS_EXEC_SET_KILL", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00200000) > 0, true, false), + "CS_EXEC_SET_ENFORCEMENT", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00400000) > 0, true, false), + "CS_EXEC_INHERIT_SIP", + iff(binary_and(toint(eventContext.codesigning_flags), 0x00800000) > 0, true, false), + "CS_KILLED", + iff(binary_and(toint(eventContext.codesigning_flags), 0x01000000) > 0, true, false), + "CS_DYLD_PLATFORM", + iff(binary_and(toint(eventContext.codesigning_flags), 0x02000000) > 0, true, false), + "CS_PLATFORM_BINARY", + iff(binary_and(toint(eventContext.codesigning_flags), 0x04000000) > 0, true, false), + "CS_PLATFORM_PATH", + iff(binary_and(toint(eventContext.codesigning_flags), 0x08000000) > 0, true, false), + "CS_DEBUGGED", + iff(binary_and(toint(eventContext.codesigning_flags), 0x10000000) > 0, true, false), + "CS_SIGNED", + iff(binary_and(toint(eventContext.codesigning_flags), 0x20000000) > 0, true, false), + "CS_DEV_CODE", + iff(binary_and(toint(eventContext.codesigning_flags), 0x40000000) > 0, true, false), + "CS_DATAVAULT_CONTROLLER", + iff(binary_and(toint(eventContext.codesigning_flags), 0x80000000) > 0, true, false) + ), "") + // Event Specific - authentication + | extend TargetUsername = + iif( + isnotempty(event[eventTypeHuman]['username']), + event[eventTypeHuman]['username'], + iif( + isnotempty(event[eventTypeHuman]['to_username']), + event[eventTypeHuman]['to_username'], + iif( + isnotempty(event[eventTypeHuman]['account_name']), + event[eventTypeHuman]['account_name'], + iif( + isnotempty(event[eventTypeHuman]['user_name']), + event[eventTypeHuman]['user_name'], + iif( + isnotempty(event[eventTypeHuman]['authentication_username']), + event[eventTypeHuman]['authentication_username'], + "" + ) + ) + ) + ) + ) + // Event Specific - authentication + | extend ActorUsername = + iif( + isnotempty(event[eventTypeHuman]['from_username']), + event[eventTypeHuman]['from_username'], + iif( + isnotempty(event[eventTypeHuman]['session_username']), + event[eventTypeHuman]['session_username'], + "" + ) + ) + | extend Authentication = iif( + eventTypeHuman == "authentication", + bag_pack( + "authentication_method", + iff(isnotempty(event[eventTypeHuman].data), tostring(bag_keys(event[eventTypeHuman].data)[0]), "") + ), + dynamic(null) + ) + // Event Specific - bios_uefi + | extend HardwareInformation = iif( + eventTypeHuman == "bios_uefi", + bag_pack( + "host_architecture", + iff(isnotempty(event[eventTypeHuman].architecture), event[eventTypeHuman].architecture, ""), + "firmware_version", + iff(isnotempty(event[eventTypeHuman].bios.['firmware-version']), event[eventTypeHuman].bios.['firmware-version'], ""), + "system_firmware_version", + iff(isnotempty(event[eventTypeHuman].bios.['system-firmware-version']), event[eventTypeHuman].bios.['system-firmware-version'], "") + ), + dynamic(null) + ) + // Event Specific - btm_launch_item_add & btm_launch_item_remove + | extend BtmItem = iif( + eventTypeHuman in ("btm_launch_item_add", "btm_launch_item_remove", "remount"), + bag_pack( + "btm_executable_path", + iff(isnotempty(event[eventTypeHuman].executable_path), event[eventTypeHuman].executable_path, ""), + "btm_item_app_url", + iff(isnotempty(event[eventTypeHuman].item.app_url), event[eventTypeHuman].item.app_url, ""), + "btm_item_url", + iff(isnotempty(event[eventTypeHuman].item.item_url), event[eventTypeHuman].item.item_url, ""), + "btm_item_managed", + iff(isnotempty(event[eventTypeHuman].item.managed), event[eventTypeHuman].item.managed, ""), + "btm_item_legacy", + iff(isnotempty(event[eventTypeHuman].item.legacy), event[eventTypeHuman].item.legacy, ""), + "btm_item_uid", + iff(isnotempty(event[eventTypeHuman].item.uid), event[eventTypeHuman].item.uid, ""), + "btm_item_type", + iff( + isnotempty(event[eventTypeHuman].item.item_type), + case( + event[eventTypeHuman].item.item_type == 0, + "UserItem", + event[eventTypeHuman].item.item_type == 1, + "App", + event[eventTypeHuman].item.item_type == 2, + "LoginItem", + event[eventTypeHuman].item.item_type == 3, + "LaunchAgent", + event[eventTypeHuman].item.item_type == 4, + "LaunchDaemon", + "Unknown" + ), + "" + ) + ), + dynamic(null) + ) + // Event Specific - chroot + | extend Chroot = iif( + eventTypeHuman == "chroot", + bag_pack( + "apparent_root_directory", + iff(isnotempty(event[eventTypeHuman].target), event[eventTypeHuman].target.path, ""), + "stats", + iff(isnotempty(event[eventTypeHuman].target.stat), event[eventTypeHuman].target.stat, "") + ), + dynamic(null) + ) + // Event Specific - cs_invalidated + // Event Specific - exec + // Event Specific - kextload & kextunload + | extend KernelExtension = iif( + eventTypeHuman in ("kextload", "kextunload"), + bag_pack( + "kext_identifier", + iff(isnotempty(event[eventTypeHuman].identifier), event[eventTypeHuman].identifier, "") + ), + dynamic(null) + ) + // Event Specific - lw_session_lock & lw_session_unlock & lw_session_login & lw_session_logout + | extend LoginWindowSession = iif( + eventTypeHuman in ("lw_session_lock", "lw_session_unlock", "lw_session_login", "lw_session_logout"), + bag_pack( + "graphical_session_id", + iff(isnotempty(event[eventTypeHuman].graphical_session_id), event[eventTypeHuman].graphical_session_id, "") + ), + dynamic(null) + ) + // Event Specific - mount & remount & unmount + | extend FileSystem = iif( + eventTypeHuman in ("mount", "unmount", "remount"), + bag_pack( + "volume_device_name", + iff(isnotempty(event[eventTypeHuman].statfs.f_mntfromname), event[eventTypeHuman].statfs.f_mntfromname, ""), + "volume_mount_name", + iff(isnotempty(event[eventTypeHuman].statfs.f_mntonname), event[eventTypeHuman].statfs.f_mntonname, ""), + "volume_file_system_type", + iff(isnotempty(event[eventTypeHuman].statfs.f_fstypename), event[eventTypeHuman].statfs.f_fstypename, ""), + "volume_size", + iff(isnotempty(event[eventTypeHuman].statfs.f_bsize), event[eventTypeHuman].statfs.f_bsize, "") + ), + dynamic(null) + ) + // Event Specific - od_attribute_set & od_attribute_value_add & od_attribute_value_remove & od_create_group & od_create_user & od_delete_group & od_delete_user & od_disable_user & od_enable_user + | extend OpenDirectory = iif( + eventTypeHuman in ("od_attribute_set", "od_attribute_value_add", "od_attribute_value_remove", "od_create_group", "od_create_user", "od_delete_group", "od_delete_user", "od_disable_user", "od_enable_user"), + bag_pack( + "group_name", + iff(isnotempty(event[eventTypeHuman].group_name), event[eventTypeHuman].group_name, ""), + "member_array", + iff(isnotempty(event[eventTypeHuman].members.member_array), event[eventTypeHuman].members.member_array, ""), + "member_value", + iff(isnotempty(event[eventTypeHuman].member.member_value), event[eventTypeHuman].member.member_value, ""), + "user_name", + iff(isnotempty(event[eventTypeHuman].user_name), event[eventTypeHuman].user_name, ""), + "account_name", + iff(isnotempty(event[eventTypeHuman].account_name), event[eventTypeHuman].account_name, ""), + "db_path", + iff(isnotempty(event[eventTypeHuman].db_path), event[eventTypeHuman].db_path, ""), + "record_name", + iff(isnotempty(event[eventTypeHuman].record_name), event[eventTypeHuman].record_name, ""), + "attribute_name", + iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, ""), + "attribute_value", + iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, ""), + "node_name", + iff(isnotempty(event[eventTypeHuman].node_name), event[eventTypeHuman].node_name, "") + ), + dynamic(null) + ) + // Event Specific - openssh_login & openssh_logout + | extend SSHContext = iif( + eventTypeHuman in ("openssh_login", "openssh_logout"), + bag_pack( + "source_address_type", + iff( + isnotempty(event[eventTypeHuman].source_address_type), + case( + event[eventTypeHuman].source_address_type == 0, + "Unknown", + event[eventTypeHuman].source_address_type == 1, + "IPv4", + event[eventTypeHuman].source_address_type == 2, + "IPv6", + event[eventTypeHuman].source_address_type == 3, + "UNIX Socket", + "Unknown" + ), + "" + ), + "result_type", + iff( + isnotempty(event[eventTypeHuman].result_type), + case( + event[eventTypeHuman].result_type == 0, + "Exceeded maximum attempts", + event[eventTypeHuman].result_type == 1, + "Denied by root", + event[eventTypeHuman].result_type == 2, + "Success", + event[eventTypeHuman].result_type == 3, + "No reason", + event[eventTypeHuman].result_type == 4, + "Password", + event[eventTypeHuman].result_type == 5, + "kbdint", + event[eventTypeHuman].result_type == 6, + "Public key", + event[eventTypeHuman].result_type == 7, + "Host based", + event[eventTypeHuman].result_type == 8, + "GSS API", + event[eventTypeHuman].result_type == 9, + "Invalid user", + "Unknown" + ), + "" + ) + ), + dynamic(null) + ) + // Event Specific - performance + // Event Specific - profile_add & profile_remove + | extend Profile = iif( + eventTypeHuman in ("profile_add", "profile_remove"), + bag_pack( + "profile_scope", + iff(isnotempty(event[eventTypeHuman].profile.scope), event[eventTypeHuman].profile.scope, ""), + "profile_identifier", + iff(isnotempty(event[eventTypeHuman].profile.identifier), event[eventTypeHuman].profile.identifiery, ""), + "profile_uuid", + iff(isnotempty(event[eventTypeHuman].profile.uuid), event[eventTypeHuman].profile.uuid, ""), + "profile_display_name", + iff(isnotempty(event[eventTypeHuman].profile.display_name), event[eventTypeHuman].profile.display_name, ""), + "profile_organization", + iff(isnotempty(event[eventTypeHuman].profile.organization), event[eventTypeHuman].profile.organization, ""), + "profile_is_updated", + iff(isnotempty(event[eventTypeHuman].is_update), event[eventTypeHuman].is_update, ""), + "profile_install_source", + iff( + isnotempty(event[eventTypeHuman].profile.install_source), + case( + event[eventTypeHuman].profile.install_source == 0, + "mdm", + event[eventTypeHuman].profile.install_source == 1, + "manual", + "Unknown" + ), + "" + ) + ), + dynamic(null) + ) + // Event Specific - screenscharing_attach & screensharing_detach + | extend Screensharing = iif( + eventTypeHuman in ("screensharing_attach", "screensharing_detach"), + bag_pack( + "existing_session", + iff(isnotempty(event[eventTypeHuman].existing_session), event[eventTypeHuman].existing_session, ""), + "graphical_session_id", + iff(isnotempty(event[eventTypeHuman].graphical_authentication_username), event[eventTypeHuman].graphical_authentication_username, ""), + "session_username", + iff(isnotempty(event[eventTypeHuman].session_username), event[eventTypeHuman].session_username, ""), + "viewer_appleid", + iff(isnotempty(event[eventTypeHuman].viewer_appleid), event[eventTypeHuman].viewer_appleid, ""), + "authentication_type", + iff(isnotempty(event[eventTypeHuman].authentication_type), event[eventTypeHuman].authentication_type, ""), + "source_address", + iff(isnotempty(event[eventTypeHuman].source_address), event[eventTypeHuman].source_address, ""), + "source_address_type", + iff( + isnotempty(event[eventTypeHuman].source_address_type), + case( + event[eventTypeHuman].source_address_type == 0, + "Unknown", + event[eventTypeHuman].source_address_type == 1, + "IPv4", + event[eventTypeHuman].source_address_type == 2, + "IPv6", + event[eventTypeHuman].source_address_type == 3, + "UNIX Socket", + "Unknown" + ), + "" + ) + ), + dynamic(null) + ) + // Event Specific - su + | extend Su = iif( + eventTypeHuman == "su", + bag_pack( + "username", + iff(isnotempty(event[eventTypeHuman].username), event[eventTypeHuman].username, ""), + "uid", + iff(isnotempty(event[eventTypeHuman].uid), event[eventTypeHuman].uid, ""), + "args", + iff(isnotempty(event[eventTypeHuman].argv), event[eventTypeHuman].argv, ""), + "env_vars", + iff(isnotempty(event[eventTypeHuman].env), event[eventTypeHuman].env, ""), + "env_count", + iff(isnotempty(event[eventTypeHuman].env_count), event[eventTypeHuman].env_count, ""), + "from_username", + iff(isnotempty(event[eventTypeHuman].from_username), event[eventTypeHuman].from_username, ""), + "to_username", + iff(isnotempty(event[eventTypeHuman].to_username), event[eventTypeHuman].to_username, ""), + "failure_message", + iff(isnotempty(event[eventTypeHuman].failure_reason), event[eventTypeHuman].failure_reason, "") + ), + dynamic(null) + ) + // Event Specific - sudo + | extend Sudo = iif( + eventTypeHuman == "sudo", + bag_pack( + "TargetProcessCommandLine", + iff(isnotempty(event[eventTypeHuman].command), event[eventTypeHuman].command, ""), + "attribute_name", + iff(isnotempty(event[eventTypeHuman].attribute_name), event[eventTypeHuman].attribute_name, ""), + "attribute_value", + iff(isnotempty(event[eventTypeHuman].attribute_value), event[eventTypeHuman].attribute_value, "") + ), + dynamic(null) + ) + // Event Specific - xp_malware_detected & xp_malware_remediated + | extend Xprotect = iif( + eventTypeHuman in ("xp_malware_detected", "xp_malware_remediated"), + bag_pack( + "detected_path", + iff(isnotempty(event[eventTypeHuman].detected_path), event[eventTypeHuman].detected_path, ""), + "remediated_path", + iff(isnotempty(event[eventTypeHuman].remediated_path), event[eventTypeHuman].remediated_path, ""), + "malware_identifier", + iff(isnotempty(event[eventTypeHuman].malware_identifier), event[eventTypeHuman].malware_identifier, ""), + "signature_version", + iff(isnotempty(event[eventTypeHuman].signature_version), event[eventTypeHuman].signature_version, "") + ), + dynamic(null) + ) + | project-away + action, + event, + process + }; + // + // Jamf Protect - Network Traffic + // + let JamfProtectNetworkTraffic_view = view () { + jamfprotect_CL + | where event_metadata_product_s == "Network Traffic Stream" + // ASIM - Common Fields + | extend EventVendor = 'Jamf' + | extend EventProduct = 'Jamf Protect - Network Traffic Stream' + | project-rename + | extend + // Jamf Protect - Common Fields + EventType = "query", + EventSubType = "request", + EventStartTime = unixtime_milliseconds_todatetime(tolong(event_receiptTime_d)), + EventResult = case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Prevented", ''), + // Jamf Protect - Source User + SrcUsermail=column_ifexists('event_user_email_s', ''), + SrcUsername = column_ifexists('event_user_name_s', ''), + // Jamf Protect - Source Device Hostnames + DvcHostname = case(isnotempty(input_host_hostname_s), input_host_hostname_s, isnotempty(host_info_host_name_s), host_info_host_name_s, event_device_userDeviceName_s), + DvcIpAddr = column_ifexists("event_source_ip_s", ""), + DvcId = column_ifexists("event_device_externalId_g", ""), + DvcOs = case(event_device_osType_s == "MAC_OS", "macOS", event_device_osType_s == "IOS", "iOS", event_device_osType_s == "ANDROID", "Android", "Other"), + SrcDeviceType = case(event_device_osType_s == "MAC_OS", "Computer", event_device_osType_s == "IOS", "Mobile Device", event_device_osType_s == "ANDROID", "Mobile Device", "Other"), + // Jamf Protect - DNS Specific + DnsQuery = column_ifexists('event_hostName_s', ''), + DvcAction = case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Blocked", ''), + DnsQueryName = column_ifexists('event_domain_s', ''), + DstIpAddr = column_ifexists('event_destination_ips_s', ''), + ThreatCategory = column_ifexists('event_eventType_description_s', ''), + DnsQueryTypeName = column_ifexists('event_dns_recordType_s', ''), + DnsResponseName = column_ifexists('event_dns_responseStatus_s', ''), + ThreatOriginalRiskLevel = column_ifexists('event_threat_result_s', '') + | project-keep + TimeGenerated, + EventVendor, + EventProduct, + EventType, + EventSubType, + EventStartTime, + EventResult, + DvcHostname, + DvcIpAddr, + DvcId, + DvcOs, + SrcDeviceType, + SrcUsermail, + SrcUsername, + DnsQuery, + DnsQueryName, + DstIpAddr, + DnsQueryTypeName, + DvcAction, + DnsResponseName, + ThreatOriginalRiskLevel + }; + // // + // // Jamf Protect - Threat Events + // // + let JamfProtectThreatEvents_view = view () { + jamfprotect_CL + | where event_metadata_product_s == "Threat Events Stream" + // ASIM - Common Fields + | extend EventVendor = 'Jamf' + | extend EventProduct = 'Jamf Protect - Threat Events Stream' + | project-rename + | extend + // Jamf Protect - Common Fields + EventStartTime = column_ifexists("event_timestamp_t", ""), + EventResult=case(event_action_s == "Blocked", "Blocked", event_action_s == "Detected", "Detected", ''), + EventReportUrl = column_ifexists("event_eventUrl_s", ""), + // Jamf Protect - Alert Details + EventSeverity = case(event_severity_d == 2, "Informational", event_severity_d == 4, "Low", event_severity_d == 6, "Medium", event_severity_d == 8, "High", event_severity_d == 10, "High", "Informational"), + // Jamf Protect - Source User + SrcUsermail=column_ifexists('event_user_email_s', ''), + SrcUsername=column_ifexists('event_user_name_s', ''), + // Jamf Protect - Source Device Hostnames + DvcHostname = column_ifexists("event_device_userDeviceName_s", ""), + DvcIpAddr = column_ifexists("event_source_ip_s", ""), + DvcId = column_ifexists("event_device_externalId_g", ""), + DvcOs=case(event_device_os_s has "MAC_OS", "macOS", event_device_os_s has "IOS", "iOS", event_device_os_s has "ANDROID", "Android", "Other"), + SrcDeviceType=case(event_device_os_s has "MAC_OS", "Computer", event_device_os_s has "IOS", "Mobile Device", event_device_os_s has "ANDROID", "Mobile Device", "Other"), + // Jamf Protect - DNS Specific + DnsQuery=column_ifexists('event_hostName_s', ''), + DvcAction=case(event_blocked_b == "false", "Allowed", event_blocked_b == "true", "Blocked", ''), + DnsQueryName=column_ifexists('event_destination_name_s', ''), + DstIpAddr=column_ifexists('event_destination_ip_s', ''), + ThreatCategory=column_ifexists('event_eventType_description_s', ''), + ThreatOriginalRiskLevel=column_ifexists('event_threat_result_s', ''), + // Jamf Protect - App Specific + TargetFileName = column_ifexists("event_app_name_s", ""), + TargetFileSHA1 = column_ifexists("event_app_sha1_s", ""), + TargetFileSHA256 = column_ifexists("event_app_sha256_s", "") + | project-keep + TimeGenerated, + EventVendor, + EventProduct, + EventStartTime, + EventResult, + EventReportUrl, + EventSeverity, + DvcHostname, + DvcIpAddr, + DvcId, + SrcDeviceType, + SrcUsermail, + SrcUsername, + DnsQuery, + DnsQueryName, + DstIpAddr, + ThreatCategory, + DvcAction, + ThreatOriginalRiskLevel, + TargetFileName, + TargetFileSHA1, + TargetFileSHA256 + }; + union isfuzzy=true JamfProtectAlerts_view, JamfProtectUnifiedLog_view, JamfProtectTelemetryv1_view, JamfProtectTelemetryv2_view, JamfProtectNetworkTraffic_view, JamfProtectThreatEvents_view